{"repo": "aiasys/aiasys", "files": {"apps/backend/docs/llm_config.md": {"37121c2d641c255f07b7458f6dd98ebf59d93eb3": {"t": 1785674628.708637, "n": 2925, "h": "373d7def187ee296", "c": "# LLM 配置与模型解析\n\n当前默认模型配置以 Step 系列模型为优先入口。`apps/backend/config.example.toml` 默认使用:\n\n```toml\n[llm]\ndefault_provider = \"stepfun\"\ndefault_model = \"step-3.7-flash\"\ntemperature = 0.6\n\n[llm.providers.stepfun]\ntype = \"openai_chat_completions\"\nbase_url = \"https://api.stepfun.com/v1\"\napi_key = \"your-stepfun-api-key\"\n\n# 纯文本模型\n[[llm.providers.stepfun.models]]\nname = \"step-router-v1\"\nmax_context_size = 256000\ncapabilities = []\n\n[[llm.providers.stepfun.models]]\nname = \"step-3.5-flash\"\nmax_context_size = 200000\ncapabilities = []\n\n# 多模态模型\n[[llm.providers.stepfun.models]]\nname = \"step-3.7-flash\"\nmax_context_size = 256000\ncapabilities = [\"thinking\", \"image_in\", \"video_in\"]\n```\n\n系统按接口协议识别服务商,当前支持:\n\n| 类型 | 用途 |\n|------|------|\n| `openai_chat_completions` | OpenAI Chat Completions 兼容接口,Step、DashScope 等走这个协议 |\n| `openai_responses` | OpenAI Responses 兼容接口 |\n| `anthropic_messages` | Anthropic Messages 兼容接口,Kimi Coding API 走这个协议 |\n\n其他服务商(OpenAI、Anthropic、Gemini 网关等)可以按它们实际兼容的协议接入。\n\n## 配置入口\n\n推荐从前端配置:\n\n1. 打开 `/analysis`。\n2. 点击左侧边栏底部的`工作区工具`。\n3. 打开`模型配置`。\n4. 添加服务商,填写 `Base URL`、协议类型、`API Key`。\n5. 在服务商卡片里点击`测试`。\n6. 点击`获取模型`批量导入模型,或手动添加模型。\n7. 在`默认模型`里选择默认 Chat 模型并保存。\n\n后端配置文件适合首次启动前预置模型:\n\n```bash\ncd apps/backend\n[ -f config.toml ] || cp config.example.toml config.toml\n```\n\n用户配置为空时,后端会把 `config.toml` 里的 `llm.providers` 同步到当前用户的全局工作区模型配置。用户已经配置过模型后,后续修改 `config.toml` 不会覆盖已有用户配置。\n\n模型列表支持两种写法:\n\n- 字符串数组:`models = [\"step-3.7-flash\"]`,capabilities 由后端按接口类型推断。\n- 对象数组:每个模型可声明 `name`、`max_context_size`、`capabilities`,用于精确区分纯文本模型和多模态模型。\n\n## 配置存储\n\n用户模型配置保存在用户默认层:\n\n```text\nworkspaces/{user_id}/global_workspace/.aiasys/llm_config.json\n```\n\n实际路径受 `WORKSPACE_DIR` 影响。默认开发环境下,`WORKSPACE_DIR` 来自:\n\n```text\napps/backend/data/workspaces\n```\n\n服务商的 API Key 会加密存储,接口返回时只给脱敏值。运行时需要真实请求时,后端从存储里读取并解密。\n\n## 主要 API\n\nLLM 配置路由挂在 `/api/llm` 下。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/llm/providers` | 列出服务商 |\n| `POST` | `/api/llm/providers` | 创建服务商 |\n| `PATCH` | `/api/llm/providers/{provider_id}` | 更新服务商 |\n| `DELETE` | `/api/llm/providers/{provider_id}` | 删除服务商,并删除关联模型 |\n| `GET` | `/api/llm/models` | 列出模型 |\n| `POST` | `/api/llm/models` | 创建模型 |\n| `GET` | `/api/llm/models/by-id?model_id={model_id}` | 获取模型详情 |\n| `PATCH` | `/api/llm/models/by-id?model_id={model_id}` | 更新模型 |\n| `DELETE` | `/api/llm/models/by-id?model_id={model_id}` | 删除模型 |\n| `POST` | `/api/llm/models/by-id/default?model_id={model_id}` | 设为默认模型 |\n| `POST` | `/api/llm/providers/{provider_id}/test` | 测试服务商连接 |\n| `POST` | `/api/llm/providers/{provider_id}/fetch_models` | 从服务商获取模型列表 |\n| `POST` | `/api/llm/defaults` | 设置默认 Chat / Embedding 模型 |\n\n## 环境变量覆盖\n\n服务端支持通过环境变量覆盖敏感配置:\n\n```bash\nAIASYS_LLM_PROVIDER_STEPFUN_API_KEY=sk-xxx\nAIASYS_LLM_PROVIDER_STEPFUN_BASE_URL=https://api.stepfun.com/v1\nAIASYS_EMBEDDING_API_KEY=sk-xxx\nAIASYS_AUTH_JWT_SECRET=your-secret\n```\n\n其中 `{PROVIDER_ID}` 是 `config.toml` 中 `llm.providers` 的键名(如 `stepfun`)。系统启动时会自动遍历所有已配置的 provider 并检查对应的环境变量。\n"}}, "docs/guides/getting-started/QUICKSTART.md": {"37121c2d641c255f07b7458f6dd98ebf59d93eb3": {"t": 1785674629.5318258, "n": 5867, "h": "a1efc9745f704d2a", "c": "# AIASys 快速启动指南\n\n> 当前版本: v0.4.27\n\n本指南用于帮助新协作者把当前仓库跑起来。当前后端运行配置使用 `apps/backend/config.toml`,前端默认从 `13000` 访问后端 `13001`。\n\n## 1. 前置要求\n\n请先确认本机已经有这些工具:\n\n- Python 3.12+\n- [uv](https://astral.sh/uv/)\n- Node.js 22+\n- npm\n- Docker,可选,用于显式登记或创建工作区 Docker 沙盒资源\n- Redis,可选,未安装时系统会回退到内存模式\n\n## 2. 准备依赖\n\n```bash\ngit clone https://github.com/AIAsys/AIASys.git\ncd AIASys\n```\n\n后端依赖:\n\n```bash\ncd apps/backend\n[ -f config.toml ] || cp config.example.toml config.toml\nuv sync\ncd ../..\n```\n\n前端依赖:\n\n```bash\ncd apps/web\nnpm ci\ncd ../..\n```\n\n说明:\n\n- 后端依赖事实源是 `apps/backend/pyproject.toml` 和 `apps/backend/uv.lock`。\n\n- `config.toml` 需要按本机模型、认证和运行时配置补齐。新增项目请优先使用 TOML。\n\n## 3. 启动开发环境\n\n项目根目录提供统一开发启动入口:\n\n```bash\n# Linux/macOS/WSL (Git Bash)\n./dev.sh\n\n# Windows PowerShell\n.\\dev.ps1\n```\n\n它会同时启动:\n\n- 后端:`http://127.0.0.1:13001`\n- 前端:`http://127.0.0.1:13000`\n\n查看状态:\n\n```bash\n# Linux/macOS/WSL (Git Bash)\n./dev.sh status\n\n# Windows PowerShell\n.\\dev.ps1 status\n```\n\n停止前台运行的开发服务时,在启动命令所在终端按 `Ctrl+C`。\n\nWindows 命令提示符(cmd)不直接支持 `.ps1` 脚本,如需使用请先调用 PowerShell:`powershell -File dev.ps1`。日常开发推荐用 Windows PowerShell 或 Git Bash。\n\n## 4. 常用配置\n\n### 首次模型配置\n\n首次启动后,需要先配置至少一个可用的 Chat 模型,否则 Agent 对话、自动任务、上下文压缩等需要模型调用的功能无法正常执行。\n\n推荐从界面配置:\n\n1. 打开 `http://localhost:13000/workspace`。\n2. 点击左侧边栏底部的`工作区工具`,进入`模型配置`。\n3. 点击`添加服务商`,填写服务商的 API 连接信息。\n4. 在服务商卡片中点击`测试`,确认 Base URL 和 API Key 可用。\n5. 点击`获取模型`批量导入模型;如果服务商不支持模型列表接口,就点击`添加模型`手动填写模型名称。\n6. 在`默认模型`里选择默认 Chat 模型,保存后回到分析页开始对话。\n\n服务商配置需要填写:\n\n| 字段 | 说明 | 示例 |\n|:---|:---|:---|\n| ID | 本地配置标识,只用于系统内部引用 | `kimi`、`my-openai` |\n| 名称 | 界面显示名称 | `Kimi`、`OpenAI` |\n| Base URL | 服务商 API 地址,通常以 `/v1` 结尾 | `https://api.kimi.com/coding/v1` |\n| 类型 | 接口协议格式 | `OpenAI Chat Completions`、`OpenAI Responses`、`Anthropic Messages` |\n| API Key | 服务商密钥 | `sk-...` |\n| 自定义请求头 | 可选,JSON 格式 | `{\"User-Agent\":\"KimiCLI/1.16.0\"}` |\n| 环境变量 | 可选,JSON 格式,适合代理配置 | `{\"HTTPS_PROXY\":\"http://127.0.0.1:7890\"}` |\n\n模型配置需要填写:\n\n| 字段 | 说明 | 示例 |\n|:---|:---|:---|\n| 模型类型 | `Chat` 用于对话和 Agent 执行,`Embedding` 用于知识库向量化 | `Chat` |\n| 实际模型标识 | API 请求里使用的模型名 | `kimi-for-coding` |\n| 显示名称 | 界面里看到的名字 | `Kimi Coding` |\n| 最大上下文长度 | 模型上下文窗口大小,单位是 token | `128000` |\n| 模型能力 | 按模型实际能力勾选 | `thinking`、`image_in` |\n\n配置完成后,分析页输入框旁边的模型选择器只会显示已启用的 Chat 模型。知识库向量化需要单独配置默认 Embedding 模型。\n\n如果新用户还没有任何可用 Chat 模型,产品内建议直接提示:\n\n> 还没有可用模型。先配置一个 Chat 模型后,AIASys 才能执行对话和自动任务。\n\n这个提示适合放在分析页输入框附近、模型选择器空列表里,以及用户点击发送但没有可用模型时的拦截弹窗里。按钮文案建议用`去配置模型`,点击后打开`模型配置`弹窗。\n\n### 后端配置\n\n```bash\ncd apps/backend\nvim config.toml\n```\n\n关键项示例:\n\n```toml\n[server]\nhost = \"0.0.0.0\"\nport = 13001\n\n[llm]\ndefault_provider = \"stepfun\"\ndefault_model = \"step-3.7-flash\"\ntemperature = 0.6\n\n[llm.providers.stepfun]\ntype = \"openai_chat_completions\"\nbase_url = \"https://api.stepfun.com/v1\"\napi_key = \"sk-...\"\n\n# 纯文本模型\n[[llm.providers.stepfun.models]]\nname = \"step-router-v1\"\nmax_context_size = 256000\ncapabilities = []\n\n[[llm.providers.stepfun.models]]\nname = \"step-3.5-flash\"\nmax_context_size = 200000\ncapabilities = []\n\n# 多模态模型\n[[llm.providers.stepfun.models]]\nname = \"step-3.7-flash\"\nmax_context_size = 256000\ncapabilities = [\"thinking\", \"image_in\", \"video_in\"]\n\n[[llm.providers.stepfun.models]]\nname = \"step-router-v2-pro\"\nmax_context_size = 190000\ncapabilities = [\"thinking\", \"image_in\"]\n```\n\n模型配置支持两种写法:\n\n- 字符串数组:`models = [\"step-3.7-flash\"]`,capabilities 由后端按接口类型推断。\n- 对象数组:每个模型可声明 `name`、`max_context_size`、`capabilities`,用于精确区分纯文本模型和多模态模型。\n\n`config.toml` 适合本地首次启动前预置模型。用户配置为空时,后端会把这里的 `llm.providers` 同步到当前用户的全局工作区模型配置中,之后界面上的模型配置会保存到:\n\n```text\nworkspaces/{user_id}/global_workspace/.aiasys/llm_config.json\n```\n\n默认代码执行路径使用本地 UV 运行环境。Docker 不作为默认 `RuntimeEnvironment`,需要在工作区的 Docker 沙盒资源中显式登记已有容器,或按镜像创建容器后再使用。容器通过 `/workspace` 访问工作区文件和产物,容器内系统依赖与 Python 环境由镜像或容器内安装提供。\n\n如果已经在界面里配置过模型,修改 `config.toml` 不会覆盖现有用户配置。需要调整时,优先在界面的`模型配置`里修改。\n\n### 前端配置\n\n单独启动前端时,可以在 `apps/web/` 下覆盖认证模式或后端地址:\n\n```bash\ncd apps/web\n\nVITE_AUTH_MODE=local VITE_API_TARGET=http://localhost:13001 npm run dev -- --port 13000\n```\n\n用根目录脚本启动时,可以覆盖前端端口:\n\n```bash\n# Linux/macOS/WSL (Git Bash)\nAIASYS_FRONTEND_PORT=13010 ./dev.sh\n\n# Windows PowerShell\n$env:AIASYS_FRONTEND_PORT=13010; .\\dev.ps1\n```\n\n## 5. 桌面版快速启动(可选)\n\n如果想用桌面版而不是浏览器:\n\n```bash\ncd apps/desktop\nnpm install\nnpm run dev\n```\n\n桌面版自动管理前后端服务,不需要单独启动 `./dev.sh`。详见 [桌面应用文档](desktop-app.md)。\n\n## 6. 验证运行状态\n\n服务启动后,可以通过以下方式验证(以下 URL 为默认值):\n\n- 前端界面:[http://localhost:13000](http://localhost:13000)\n- 分析页:[http://localhost:13000/workspace](http://localhost:13000/workspace)\n- 后端健康检查:\n\n ```bash\n curl http://localhost:13001/health\n ```\n\n- Docker daemon 状态,可用于判断工作区 Docker 沙盒资源是否可用:\n\n ```bash\n curl http://localhost:13001/health/docker\n ```\n\n## 7. 常用开发命令\n\n| 任务 | 命令 | 路径 |\n|:---|:---|:---|\n| 安装后端依赖 | `uv sync` | `apps/backend/` |\n| 安装前端依赖 | `npm ci` | `apps/web/` |\n| 启动开发环境 | `./dev.sh`(Linux/macOS/WSL/Git Bash)
`.\\dev.ps1`(Windows PowerShell) | 项目根目录 |\n| 查看开发环境状态 | `./dev.sh status`(Linux/macOS/WSL/Git Bash)
`.\\dev.ps1 status`(Windows PowerShell) | 项目根目录 |\n| 后端启动 | `uv run uvicorn app.main:app --host 0.0.0.0 --port 13001` | `apps/backend/` |\n| 前端启动 | `npm run dev` | `apps/web/` |\n| 运行后端测试 | `uv run pytest` | `apps/backend/` |\n| 前端构建 | `npm run build` | `apps/web/` |\n| 校验视觉基线 | `./dev.sh design-lint`(Linux/macOS/WSL/Git Bash)
`.\\dev.ps1 design-lint`(Windows PowerShell) | 项目根目录 |\n| 桌面版开发 | `npm run dev` | `apps/desktop/` |\n| 桌面版 Linux 打包 | `npm run dist:linux:dir` | `apps/desktop/` |\n| 桌面版 Windows 打包 | `npm run dist:win` | `apps/desktop/` |\n| 桌面版 macOS 打包 | `npm run dist:mac` | `apps/desktop/` |\n\n---\n\n遇到启动问题时,先看 [../../deployment.md](../../deployment.md)。\n\n---\n\n## 8. 界面预览\n\n启动成功后,你可以访问:\n\n- 首页:`http://localhost:13000`\n- 分析工作区:`http://localhost:13000/workspace`\n\n分析工作区是当前主界面,左侧 Activity Bar 默认提供当前工作区、全局工作区、数据查询、文件搜索、专家协作节点、文件变更六个入口;自动化任务、监控任务、终端、环境变量、能力管理等通过工作区工具菜单或设置面板进入。右侧聊天侧栏用于与 Agent 对话和查看执行上下文。\n\n\n\n\n"}}, "docs/guides/agent/llm-thinking-config.md": {"37121c2d641c255f07b7458f6dd98ebf59d93eb3": {"t": 1785674633.290025, "n": 3137, "h": "a529b00b6affd28c", "c": "# LLM Thinking / Reasoning 配置指南\n\n## 概述\n\nAIASys 支持为支持 reasoning(深度思考)的模型配置思考深度和 reasoning 内容解析方式。当前已验证支持:\n\n- **阶跃星辰(StepFun)**:step-3.5-flash-2603\n- **DeepSeek**:deepseek-chat、deepseek-reasoner 等\n- **Kimi**:kimi-for-coding、kimi-k2 系列\n- **Anthropic**:Claude Opus 4 / Claude Sonnet 4 / Claude Haiku 3.5\n\n## Provider 配置\n\n### 基础连接信息\n\n在\"设置 > 模型服务商\"中配置服务商时,需要填写:\n\n| 字段 | 说明 | 示例 |\n|------|------|------|\n| ID | 唯一标识 | `stepfun` |\n| 名称 | 显示名称 | `阶跃星辰` |\n| 类型 | 接口协议 | `openai_chat_completions` |\n| Base URL | API 地址 | `https://api.stepfun.com/v1` |\n| API Key | 密钥 | `sk-...` |\n\n### Thinking 相关字段\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `reasoning_key` | string | API 返回 reasoning 内容时使用的字段名。不填则默认按 `reasoning_content` 解析。阶跃需要填 `reasoning`。 |\n| `reasoning_format` | string | 仅阶跃支持。可选 `general`(默认)或 `deepseek-style`。控制返回字段名:`general` 用 `reasoning`,`deepseek-style` 用 `reasoning_content`。 |\n\n## 各厂商配置对照\n\n### 阶跃星辰(StepFun)\n\n```json\n{\n \"id\": \"stepfun\",\n \"name\": \"阶跃星辰\",\n \"type\": \"openai_chat_completions\",\n \"base_url\": \"https://api.stepfun.com/v1\",\n \"reasoning_key\": \"reasoning\",\n \"reasoning_format\": \"general\"\n}\n```\n\n**重要**:阶跃默认返回的 reasoning 字段名是 `reasoning`,不是 `reasoning_content`。如果不配置 `reasoning_key: \"reasoning\"`,系统将解析不到 reasoning 内容。\n\n支持的模型和 thinking 参数:\n\n| 模型 | reasoning_effort | 说明 |\n|------|-----------------|------|\n| step-3.5-flash-2603 | `low` / `high` | 支持 thinking,可配置 effort |\n| step-3.5-flash | 不支持 | 普通对话模型 |\n| step-3.7-flash | 待验证 | 内测阶段,仅标准 API |\n\n### DeepSeek\n\n```json\n{\n \"id\": \"deepseek\",\n \"name\": \"DeepSeek\",\n \"type\": \"openai_chat_completions\",\n \"base_url\": \"https://api.deepseek.com/v1\",\n \"reasoning_key\": \"reasoning_content\"\n}\n```\n\nDeepSeek 默认返回 `reasoning_content` 字段,与系统默认值一致,可不配置 `reasoning_key`。\n\n### Kimi(Moonshot)\n\n```json\n{\n \"id\": \"kimi\",\n \"name\": \"Kimi\",\n \"type\": \"openai_chat_completions\",\n \"base_url\": \"https://api.moonshot.cn/v1\"\n}\n```\n\nKimi 的 thinking 参数通过 `extra_body.thinking.type` 控制,系统已内置适配,无需额外配置 `reasoning_key`。\n\n### Anthropic(Claude)\n\n```json\n{\n \"id\": \"anthropic\",\n \"name\": \"Anthropic\",\n \"type\": \"anthropic_messages\",\n \"base_url\": \"https://api.anthropic.com/v1\"\n}\n```\n\nAnthropic 使用独立的 Messages API 协议,thinking 配置通过 `thinking.type` 和 `output_config.effort` 控制,系统已完整适配 adaptive / legacy 两种模式。\n\n## 模型配置\n\n在\"设置 > 模型配置\"中为模型启用 thinking 能力:\n\n```json\n{\n \"id\": \"stepfun-step-3.5-flash-2603\",\n \"name\": \"step-3.5-flash-2603\",\n \"provider\": \"stepfun\",\n \"model\": \"step-3.5-flash-2603\",\n \"capabilities\": [\"thinking\", \"image_in\"],\n \"thinking_effort\": \"high\"\n}\n```\n\n| 字段 | 说明 |\n|------|------|\n| `capabilities` | 包含 `\"thinking\"` 表示该模型支持 thinking 开关;包含 `\"always_thinking\"` 表示该模型固定开启 thinking |\n| `thinking_effort` | 思考深度:`low` / `medium` / `high`。不同模型支持的级别不同 |\n\n## 前端使用\n\n配置完成后,在对话输入区:\n\n1. **模型选择器**:选择支持 thinking 的模型\n2. **思考模式**:在模型选择器下拉面板中开启/关闭 thinking,选择 effort 级别\n3. **思考内容展示**:模型回复时会显示\"思考过程\"折叠面板,可展开查看 reasoning 内容\n\n## 故障排查\n\n### 开了 thinking 但看不到 reasoning 内容\n\n1. 检查 provider 是否配置了正确的 `reasoning_key`\n2. 检查模型 capabilities 是否包含 `\"thinking\"`\n3. 检查模型是否配置了 `thinking_effort`\n\n### API 返回 400 关于 reasoning\n\n1. 确认模型是否支持 thinking(不是所有模型都支持)\n2. 确认 `reasoning_effort` 值是否在模型支持范围内(阶跃仅支持 `low` / `high`)\n"}}, "scripts/security/pre-commit-scan.sh": {"37121c2d641c255f07b7458f6dd98ebf59d93eb3": {"t": 1785747463.3075724, "n": 1815, "h": "4c2d2c260c0eecdc", "c": "#!/usr/bin/env bash\n#\n# Pre-commit hook:扫描暂存区中的潜在敏感信息。\n# 用法:由 .pre-commit-config.yaml 自动调用\n\nset -uo pipefail\n\nREPO_ROOT=\"$(cd \"$(dirname \"$0\")/../..\" && pwd)\"\ncd \"$REPO_ROOT\"\n\n# 颜色\nRED='\\033[0;31m'\nYELLOW='\\033[1;33m'\nNC='\\033[0m'\n\n# 要拦截的模式(只匹配新增/修改的行)\nPATTERNS=(\n 'sk-[a-f0-9]{32}' # Kimi / DashScope / DeepSeek 32位\n 'sk-kimi-[a-zA-Z0-9]{20,}' # Kimi 长格式\n 'sk-[a-zA-Z0-9]{48}' # OpenAI 48位\n 'sk-ant-[a-zA-Z0-9]{20,}' # Anthropic\n 'SG\\.[a-zA-Z0-9]{22}\\.[a-zA-Z0-9]{43}' # SendGrid\n 'ghp_[a-zA-Z0-9]{36}' # GitHub Classic\n 'github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}' # GitHub Fine-grained\n 'AKIA[0-9A-Z]{16}' # AWS Access Key\n)\n\n# 误报排除(示例、占位符、文档说明)\nEXCLUDE_REGEX='(your-|YOUR_|example|EXAMPLE|placeholder|PLACEHOLDER|REDACTED|redacted|xxxxxxxx|XXXXXXXX|abc123|abcdefghijklmnopqrstuvwxyz|test-secret|test_key|demo-|DEMO-|sample|SAMPLE|fake-|FAKE-|mock-|MOCK-|preview-token|local-jwt-token|none-mode-token|App Secret|Verify Token|Client Secret|Bot Token|App Token|Access Token|Password|Auth Token|\\$GITHUB_TOKEN|\\$KIMI_API_KEY|sha256=|api_key\\.py|api-key)'\n\nHITS=0\n\nfor pattern in \"${PATTERNS[@]}\"; do\n # 只扫描暂存区中的文本文件(新增或修改的内容)\n matches=$(git diff --cached --no-color | grep -E \"^[+]\" | grep -vE \"^\\+\\+\\+\" | grep -E \"$pattern\" | grep -vE \"$EXCLUDE_REGEX\" || true)\n\n if [ -n \"$matches\" ]; then\n HITS=$((HITS + 1))\n echo \"${RED}[BLOCKED]${NC} 暂存区检测到可疑模式: $pattern\"\n echo \"$matches\" | head -5 | while IFS= read -r line; do\n echo \" $line\"\n done\n echo \"\"\n fi\ndone\n\nif [ \"$HITS\" -gt 0 ]; then\n echo \"${RED}发现 $HITS 条潜在敏感信息。${NC}\"\n echo \"如果确认是误报,可用 git commit --no-verify 跳过本次检查。\"\n echo \"但请不要将真实 API key、密码、token 提交到仓库。\"\n exit 1\nfi\n\nexit 0\n"}, "85f1487c617febae9466ee2a85d94fee07aaa9b6": {"t": 1785773446.621322, "n": 1815, "h": "4c2d2c260c0eecdc", "c": "#!/usr/bin/env bash\n#\n# Pre-commit hook:扫描暂存区中的潜在敏感信息。\n# 用法:由 .pre-commit-config.yaml 自动调用\n\nset -uo pipefail\n\nREPO_ROOT=\"$(cd \"$(dirname \"$0\")/../..\" && pwd)\"\ncd \"$REPO_ROOT\"\n\n# 颜色\nRED='\\033[0;31m'\nYELLOW='\\033[1;33m'\nNC='\\033[0m'\n\n# 要拦截的模式(只匹配新增/修改的行)\nPATTERNS=(\n 'sk-[a-f0-9]{32}' # Kimi / DashScope / DeepSeek 32位\n 'sk-kimi-[a-zA-Z0-9]{20,}' # Kimi 长格式\n 'sk-[a-zA-Z0-9]{48}' # OpenAI 48位\n 'sk-ant-[a-zA-Z0-9]{20,}' # Anthropic\n 'SG\\.[a-zA-Z0-9]{22}\\.[a-zA-Z0-9]{43}' # SendGrid\n 'ghp_[a-zA-Z0-9]{36}' # GitHub Classic\n 'github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}' # GitHub Fine-grained\n 'AKIA[0-9A-Z]{16}' # AWS Access Key\n)\n\n# 误报排除(示例、占位符、文档说明)\nEXCLUDE_REGEX='(your-|YOUR_|example|EXAMPLE|placeholder|PLACEHOLDER|REDACTED|redacted|xxxxxxxx|XXXXXXXX|abc123|abcdefghijklmnopqrstuvwxyz|test-secret|test_key|demo-|DEMO-|sample|SAMPLE|fake-|FAKE-|mock-|MOCK-|preview-token|local-jwt-token|none-mode-token|App Secret|Verify Token|Client Secret|Bot Token|App Token|Access Token|Password|Auth Token|\\$GITHUB_TOKEN|\\$KIMI_API_KEY|sha256=|api_key\\.py|api-key)'\n\nHITS=0\n\nfor pattern in \"${PATTERNS[@]}\"; do\n # 只扫描暂存区中的文本文件(新增或修改的内容)\n matches=$(git diff --cached --no-color | grep -E \"^[+]\" | grep -vE \"^\\+\\+\\+\" | grep -E \"$pattern\" | grep -vE \"$EXCLUDE_REGEX\" || true)\n\n if [ -n \"$matches\" ]; then\n HITS=$((HITS + 1))\n echo \"${RED}[BLOCKED]${NC} 暂存区检测到可疑模式: $pattern\"\n echo \"$matches\" | head -5 | while IFS= read -r line; do\n echo \" $line\"\n done\n echo \"\"\n fi\ndone\n\nif [ \"$HITS\" -gt 0 ]; then\n echo \"${RED}发现 $HITS 条潜在敏感信息。${NC}\"\n echo \"如果确认是误报,可用 git commit --no-verify 跳过本次检查。\"\n echo \"但请不要将真实 API key、密码、token 提交到仓库。\"\n exit 1\nfi\n\nexit 0\n"}}, "scripts/security/scan-secrets.sh": {"37121c2d641c255f07b7458f6dd98ebf59d93eb3": {"t": 1785747466.322836, "n": 3734, "h": "0cf55b039ca99e1a", "c": "#!/usr/bin/env bash\n#\n# 扫描 git 历史中的潜在敏感信息泄露。\n# 用法: cd /home/ke/projects/AIASys && bash scripts/security/scan-secrets.sh\n\nset -euo pipefail\n\nREPO_ROOT=\"$(cd \"$(dirname \"$0\")/../..\" && pwd)\"\ncd \"$REPO_ROOT\"\n\n# 颜色\nRED='\\033[0;31m'\nYELLOW='\\033[1;33m'\nGREEN='\\033[0;32m'\nNC='\\033[0m'\n\n# 已知的误报模式(示例、占位符、文档说明)\nEXCLUDE_PATTERNS=(\n # 文档/注释中的占位符\n 'your-'\n 'YOUR_'\n 'example'\n 'EXAMPLE'\n 'placeholder'\n 'PLACEHOLDER'\n 'REDACTED'\n 'redacted'\n 'xxxxxxxx'\n 'XXXXXXXX'\n 'abc123'\n 'abcdefghijklmnopqrstuvwxyz'\n 'test-secret'\n 'test_key'\n 'demo-'\n 'DEMO_'\n 'sample'\n 'SAMPLE'\n 'fake-'\n 'FAKE_'\n 'mock-'\n 'MOCK_'\n 'none-mode-token'\n 'local-jwt-token'\n 'preview-token'\n 'App Secret'\n 'Verify Token'\n 'Client Secret'\n 'Bot Token'\n 'App Token'\n 'Access Token'\n 'Password'\n 'Auth Token'\n # 环境变量引用\n '\\$GITHUB_TOKEN'\n '\\$KIMI_API_KEY'\n # 脚本中的变量名\n 'api_key_encrypted'\n # 格式说明\n '正则表达式'\n '前缀特征'\n '示例'\n '应该被检测'\n '不应该被误报'\n # SHA256 哈希(非 key)\n 'sha256='\n # 文件路径中的 key 字样\n 'api_key.py'\n 'api-key'\n)\n\n# 构建 grep 排除参数\nEXCLUDE_ARGS=()\nfor pat in \"${EXCLUDE_PATTERNS[@]}\"; do\n EXCLUDE_ARGS+=(\"--exclude\")\n EXCLUDE_ARGS+=(\"$pat\")\ndone\n\necho \"========================================\"\necho \"Git 历史敏感信息扫描\"\necho \"仓库: $REPO_ROOT\"\necho \"========================================\"\necho \"\"\n\n# 要扫描的正则模式\nPATTERNS=(\n # Kimi (32位十六进制)\n 'sk-[a-f0-9]{32}'\n # Kimi (长格式)\n 'sk-kimi-[a-zA-Z0-9]{20,}'\n # OpenAI (48位)\n 'sk-[a-zA-Z0-9]{48}'\n # Anthropic\n 'sk-ant-[a-zA-Z0-9]{20,}'\n # DashScope / DeepSeek (32位)\n 'sk-[a-f0-9]{32}'\n # SendGrid\n 'SG\\.[a-zA-Z0-9]{22}\\.[a-zA-Z0-9]{43}'\n # GitHub Token (经典)\n 'ghp_[a-zA-Z0-9]{36}'\n # GitHub Token (细粒度)\n 'github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}'\n # AWS Access Key\n 'AKIA[0-9A-Z]{16}'\n # 通用 UUID-like API key (32位十六进制,带 key/secret/token 上下文)\n '(api[_-]?key|secret|token|password)\\s*[:=]\\s*[\"'\\''\"'\\''`][a-f0-9]{32}[\"'\\''\"'\\''`\"]'\n)\n\nTOTAL_HITS=0\nSUSPICIOUS_HITS=0\n\nfor pattern in \"${PATTERNS[@]}\"; do\n echo \"--- 扫描模式: $pattern ---\"\n\n # 从 git 历史中扫描(所有提交的 patch)\n # 使用 git log -p 输出所有提交的 diff,然后 grep 匹配\n # 限制输出前 50 条,避免太多\n hits=$(git log --all -p 2>/dev/null | grep -nE \"^[+-].*$pattern\" | head -50 || true)\n\n if [ -z \"$hits\" ]; then\n echo \" ${GREEN}未命中${NC}\"\n continue\n fi\n\n line_count=$(echo \"$hits\" | wc -l)\n TOTAL_HITS=$((TOTAL_HITS + line_count))\n\n # 过滤误报\n filtered=\"$hits\"\n for pat in \"${EXCLUDE_PATTERNS[@]}\"; do\n filtered=$(echo \"$filtered\" | grep -vF \"$pat\" || true)\n done\n\n if [ -z \"$filtered\" ]; then\n echo \" ${GREEN}命中 $line_count 条,全部确认为误报/示例${NC}\"\n continue\n fi\n\n filtered_count=$(echo \"$filtered\" | wc -l)\n SUSPICIOUS_HITS=$((SUSPICIOUS_HITS + filtered_count))\n\n echo \" ${YELLOW}命中 $line_count 条,其中 $filtered_count 条需要人工复核${NC}\"\n echo \"$filtered\" | while IFS= read -r line; do\n # 截断过长的行\n if [ \"${#line}\" -gt 200 ]; then\n line=\"${line:0:200}...\"\n fi\n echo \" $line\"\n done\n echo \"\"\ndone\n\necho \"\"\necho \"========================================\"\necho \"扫描完成\"\necho \"总命中数: $TOTAL_HITS\"\necho \"需复核数: $SUSPICIOUS_HITS\"\n\nif [ \"$SUSPICIOUS_HITS\" -gt 0 ]; then\n echo \"\"\n echo \"${RED}发现 $SUSPICIOUS_HITS 条可疑记录,请逐一人工复核。${NC}\"\n echo \"如果确认是真实 key,请:\"\n echo \" 1. 立即到对应平台撤销(rotate)该 key\"\n echo \" 2. 用 git-filter-repo 或 BFG 清理 git 历史\"\n echo \" 3. 通知所有团队成员重新 clone 仓库\"\n exit 1\nelse\n echo \"${GREEN}未发现需要复核的可疑记录。${NC}\"\n echo \"\"\n echo \"建议后续配置:\"\n echo \" 1. 安装 git-secrets: apt install git-secrets\"\n echo \" 2. 配置 pre-commit hook 阻止含 key 的提交\"\n exit 0\nfi\n"}, "85f1487c617febae9466ee2a85d94fee07aaa9b6": {"t": 1785773445.6432395, "n": 3734, "h": "0cf55b039ca99e1a", "c": "#!/usr/bin/env bash\n#\n# 扫描 git 历史中的潜在敏感信息泄露。\n# 用法: cd /home/ke/projects/AIASys && bash scripts/security/scan-secrets.sh\n\nset -euo pipefail\n\nREPO_ROOT=\"$(cd \"$(dirname \"$0\")/../..\" && pwd)\"\ncd \"$REPO_ROOT\"\n\n# 颜色\nRED='\\033[0;31m'\nYELLOW='\\033[1;33m'\nGREEN='\\033[0;32m'\nNC='\\033[0m'\n\n# 已知的误报模式(示例、占位符、文档说明)\nEXCLUDE_PATTERNS=(\n # 文档/注释中的占位符\n 'your-'\n 'YOUR_'\n 'example'\n 'EXAMPLE'\n 'placeholder'\n 'PLACEHOLDER'\n 'REDACTED'\n 'redacted'\n 'xxxxxxxx'\n 'XXXXXXXX'\n 'abc123'\n 'abcdefghijklmnopqrstuvwxyz'\n 'test-secret'\n 'test_key'\n 'demo-'\n 'DEMO_'\n 'sample'\n 'SAMPLE'\n 'fake-'\n 'FAKE_'\n 'mock-'\n 'MOCK_'\n 'none-mode-token'\n 'local-jwt-token'\n 'preview-token'\n 'App Secret'\n 'Verify Token'\n 'Client Secret'\n 'Bot Token'\n 'App Token'\n 'Access Token'\n 'Password'\n 'Auth Token'\n # 环境变量引用\n '\\$GITHUB_TOKEN'\n '\\$KIMI_API_KEY'\n # 脚本中的变量名\n 'api_key_encrypted'\n # 格式说明\n '正则表达式'\n '前缀特征'\n '示例'\n '应该被检测'\n '不应该被误报'\n # SHA256 哈希(非 key)\n 'sha256='\n # 文件路径中的 key 字样\n 'api_key.py'\n 'api-key'\n)\n\n# 构建 grep 排除参数\nEXCLUDE_ARGS=()\nfor pat in \"${EXCLUDE_PATTERNS[@]}\"; do\n EXCLUDE_ARGS+=(\"--exclude\")\n EXCLUDE_ARGS+=(\"$pat\")\ndone\n\necho \"========================================\"\necho \"Git 历史敏感信息扫描\"\necho \"仓库: $REPO_ROOT\"\necho \"========================================\"\necho \"\"\n\n# 要扫描的正则模式\nPATTERNS=(\n # Kimi (32位十六进制)\n 'sk-[a-f0-9]{32}'\n # Kimi (长格式)\n 'sk-kimi-[a-zA-Z0-9]{20,}'\n # OpenAI (48位)\n 'sk-[a-zA-Z0-9]{48}'\n # Anthropic\n 'sk-ant-[a-zA-Z0-9]{20,}'\n # DashScope / DeepSeek (32位)\n 'sk-[a-f0-9]{32}'\n # SendGrid\n 'SG\\.[a-zA-Z0-9]{22}\\.[a-zA-Z0-9]{43}'\n # GitHub Token (经典)\n 'ghp_[a-zA-Z0-9]{36}'\n # GitHub Token (细粒度)\n 'github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}'\n # AWS Access Key\n 'AKIA[0-9A-Z]{16}'\n # 通用 UUID-like API key (32位十六进制,带 key/secret/token 上下文)\n '(api[_-]?key|secret|token|password)\\s*[:=]\\s*[\"'\\''\"'\\''`][a-f0-9]{32}[\"'\\''\"'\\''`\"]'\n)\n\nTOTAL_HITS=0\nSUSPICIOUS_HITS=0\n\nfor pattern in \"${PATTERNS[@]}\"; do\n echo \"--- 扫描模式: $pattern ---\"\n\n # 从 git 历史中扫描(所有提交的 patch)\n # 使用 git log -p 输出所有提交的 diff,然后 grep 匹配\n # 限制输出前 50 条,避免太多\n hits=$(git log --all -p 2>/dev/null | grep -nE \"^[+-].*$pattern\" | head -50 || true)\n\n if [ -z \"$hits\" ]; then\n echo \" ${GREEN}未命中${NC}\"\n continue\n fi\n\n line_count=$(echo \"$hits\" | wc -l)\n TOTAL_HITS=$((TOTAL_HITS + line_count))\n\n # 过滤误报\n filtered=\"$hits\"\n for pat in \"${EXCLUDE_PATTERNS[@]}\"; do\n filtered=$(echo \"$filtered\" | grep -vF \"$pat\" || true)\n done\n\n if [ -z \"$filtered\" ]; then\n echo \" ${GREEN}命中 $line_count 条,全部确认为误报/示例${NC}\"\n continue\n fi\n\n filtered_count=$(echo \"$filtered\" | wc -l)\n SUSPICIOUS_HITS=$((SUSPICIOUS_HITS + filtered_count))\n\n echo \" ${YELLOW}命中 $line_count 条,其中 $filtered_count 条需要人工复核${NC}\"\n echo \"$filtered\" | while IFS= read -r line; do\n # 截断过长的行\n if [ \"${#line}\" -gt 200 ]; then\n line=\"${line:0:200}...\"\n fi\n echo \" $line\"\n done\n echo \"\"\ndone\n\necho \"\"\necho \"========================================\"\necho \"扫描完成\"\necho \"总命中数: $TOTAL_HITS\"\necho \"需复核数: $SUSPICIOUS_HITS\"\n\nif [ \"$SUSPICIOUS_HITS\" -gt 0 ]; then\n echo \"\"\n echo \"${RED}发现 $SUSPICIOUS_HITS 条可疑记录,请逐一人工复核。${NC}\"\n echo \"如果确认是真实 key,请:\"\n echo \" 1. 立即到对应平台撤销(rotate)该 key\"\n echo \" 2. 用 git-filter-repo 或 BFG 清理 git 历史\"\n echo \" 3. 通知所有团队成员重新 clone 仓库\"\n exit 1\nelse\n echo \"${GREEN}未发现需要复核的可疑记录。${NC}\"\n echo \"\"\n echo \"建议后续配置:\"\n echo \" 1. 安装 git-secrets: apt install git-secrets\"\n echo \" 2. 配置 pre-commit hook 阻止含 key 的提交\"\n exit 0\nfi\n"}}}}