Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
1 line
74 KiB
JSON
1 line
74 KiB
JSON
{"repo": "calwd0mn/pico-ts", "files": {"README.md": {"74022538904a2ca69d28689d30d5e5284e09fb15": {"t": 1785746718.795921, "n": 6794, "h": "d77fa039a002bd57", "c": "# pico\n\n`pico` 是一个面向代码仓库的轻量本地 coding agent。它直接跑在终端里,先看当前工作区,再用一组受约束的工具去读文件、改文件、跑命令,并把会话状态保存在本地 `.pico/` 目录里。\n\n它更像一个能在仓库里持续工作的命令行助手,不是纯聊天窗口。你可以拿它做代码排查、测试修复、仓库分析,或者让它在当前项目里执行一次性的工程任务。\n\n## 适合做什么\n\n- 在本地仓库里排查测试失败\n- 读取当前代码结构并给出修改建议\n- 基于现有文件做小步迭代,而不是脱离仓库空想\n- 在会话中保留上下文,支持继续上一次工作\n\n## 主要特性\n\n- 包名是 `pico`\n- CLI 命令是 `pico`\n- 模块入口是 `python -m pico`\n- 会话保存在 `.pico/sessions/`\n- 每次运行的工件保存在 `.pico/runs/<run_id>/`\n- 支持四类模型后端:\n - Ollama\n - OpenAI 兼容 Responses API\n - Anthropic 兼容 Messages API\n - DeepSeek Anthropic 兼容 API\n\n## 使用截图\n\nCLI 帮助信息:\n\n\n\n启动界面:\n\n\n\nREPL 内置命令与会话路径:\n\n\n\n## 安装\n\n需要 Python 3.10+。\n\n如果你用 `uv`,直接安装依赖:\n\n```bash\nuv sync\n```\n\n如果你已经在自己的 Python 环境里工作,也可以直接装成可编辑模式:\n\n```bash\npip install -e .\n```\n\n## TypeScript 版本\n\n仓库同时提供独立的 Node.js 20+ 实现,代码位于 `ts-pico/`。它使用相同的工作区工具、会话、上下文和 provider 概念,但运行产物写入 `.tspico/`,不会与 Python 版本的 `.pico/` 混用。\n\n```bash\ncd ts-pico\nnpm install\nnpm run dev -- \"inspect the repository and summarize the runtime flow\"\n```\n\n常用开发命令:\n\n```bash\nnpm run check\nnpm test\nnpm run build\n```\n\nTypeScript CLI 支持与 Python CLI 对应的 provider、会话恢复和预算参数,例如:\n\n```bash\nnpm run dev -- --provider deepseek --max-steps 24 --max-new-tokens 1024\nnpm run dev -- --resume latest\n```\n\n## 快速开始\n\n在当前仓库里启动交互模式。默认 provider 是 DeepSeek:\n\n```bash\nuv run pico\n```\n\n指定另一个工作目录:\n\n```bash\nuv run pico --cwd /path/to/repo\n```\n\n直接跑一次性任务:\n\n```bash\nuv run pico \"inspect the test failures and propose a fix\"\n```\n\n如果当前环境已经安装过包,也可以直接这样启动:\n\n```bash\npython -m pico\n```\n\n## 模型后端\n\nPico 启动时会读取项目根目录的 `.env`。本地真实 key 放在 `.env`,仓库只保留 `.env.example`。配置优先级是:\n\n```text\n显式 CLI 参数 > .env 里的 PICO_* 变量 > 旧环境变量 > 代码默认值\n```\n\nProvider 选择的具体顺序是:\n\n```text\n--provider > PICO_PROVIDER > 代码默认 deepseek\n```\n\n不传 `--provider` 且没有 `PICO_PROVIDER` 时默认使用 `deepseek`。这是推荐配置路径:DeepSeek 的 Anthropic-compatible endpoint 比本地 Ollama 更少依赖本机模型环境,也比 OpenAI-compatible/Anthropic-compatible 代理少一层默认 gateway 假设。其他 provider 仍然保留,可以在 `.env` 里写 `PICO_PROVIDER=openai`、`PICO_PROVIDER=anthropic`、`PICO_PROVIDER=ollama`,也可以显式传 `--provider openai`、`--provider anthropic` 或 `--provider ollama`。\n\n`.env` 会在构建 provider client 前加载,并覆盖当前进程里的同名环境变量。模型名和 base URL 可以通过 `--model`、`--base-url` 临时覆盖;API key 只从环境变量读取。\n\n本地第一次配置:\n\n```bash\ncp .env.example .env\n```\n\n然后把要使用的 provider key 填进去。`.env` 已经被 `.gitignore` 忽略,不要提交真实 key。\n\n### 推荐配置:DeepSeek\n\n最小配置只需要 key:\n\n```bash\nPICO_DEEPSEEK_API_KEY=\"your-api-key\"\n```\n\n默认模型和接口是:\n\n```bash\nPICO_DEEPSEEK_API_BASE=\"https://api.deepseek.com/anthropic\"\nPICO_DEEPSEEK_MODEL=\"deepseek-v4-pro\"\n```\n\n所以常规情况下 `.env` 里只填 `PICO_DEEPSEEK_API_KEY` 就能直接启动:\n\n```bash\nuv run pico\n```\n\n如果你需要临时切模型或代理地址,不必改 `.env`,可以直接覆盖:\n\n```bash\nuv run pico --model deepseek-v4-pro --base-url https://api.deepseek.com/anthropic\n```\n\nDeepSeek 当前走 Anthropic-compatible Messages API,所以 runtime 里复用的是 Anthropic-compatible client;这只影响 HTTP 协议,不影响 CLI 用法。\n\n### 可选配置:right.codes\n\nright.codes 在 Pico 里有两条可选 provider 路径:\n\n- `--provider openai`:走 OpenAI-compatible `/responses`,默认 base URL 是 `https://www.right.codes/codex/v1`,默认模型是 `gpt-5.4`\n- `--provider anthropic`:走 Anthropic-compatible `/messages`,默认 base URL 是 `https://www.right.codes/claude/v1`,默认模型是 `claude-sonnet-4-6`\n\n如果 right.codes 给你的是一把共享 key,推荐只填这一项:\n\n```bash\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\n```\n\n然后按需要选择 provider:\n\n```bash\nuv run pico --provider openai\nuv run pico --provider anthropic\n```\n\n如果你想显式区分两条 provider 的 key,也可以分别配置:\n\n```bash\nPICO_OPENAI_API_KEY=\"your-right-codes-key-for-codex\"\nPICO_ANTHROPIC_API_KEY=\"your-right-codes-key-for-claude\"\n```\n\n不要在 `.env` 里写 `PICO_OPENAI_API_KEY=$PICO_RIGHT_CODES_API_KEY` 这种 shell 展开形式;Pico 的 `.env` 解析器只读取字面量,不展开变量引用。要么只写 `PICO_RIGHT_CODES_API_KEY`,要么把 key 字符串分别填到 provider-specific 变量里。\n\n如果请求 right.codes 返回 `API Key额度不足`,说明协议和 endpoint 已经打通,但当前 key 没有可用额度;换一把有额度的 key,或到 right.codes 后台处理额度。\n\n当前 provider 环境变量:\n\n| provider | base URL | API key | model |\n| --- | --- | --- | --- |\n| `deepseek` | `PICO_DEEPSEEK_API_BASE`,回退 `DEEPSEEK_API_BASE`,默认 `https://api.deepseek.com/anthropic` | `PICO_DEEPSEEK_API_KEY`,回退 `DEEPSEEK_API_KEY` | `PICO_DEEPSEEK_MODEL`,回退 `DEEPSEEK_MODEL`,默认 `deepseek-v4-pro` |\n| `openai` | `PICO_OPENAI_API_BASE`,回退 `OPENAI_API_BASE`,默认 `https://www.right.codes/codex/v1` | `PICO_OPENAI_API_KEY`,回退 `OPENAI_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_ANTHROPIC_API_KEY`、`ANTHROPIC_API_KEY` | `PICO_OPENAI_MODEL`,回退 `OPENAI_MODEL`,默认 `gpt-5.4` |\n| `anthropic` | `PICO_ANTHROPIC_API_BASE`,回退 `ANTHROPIC_API_BASE`,默认 `https://www.right.codes/claude/v1` | `PICO_ANTHROPIC_API_KEY`,回退 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY`、`OPENAI_API_KEY` | `PICO_ANTHROPIC_MODEL`,回退 `ANTHROPIC_MODEL`,默认 `claude-sonnet-4-6` |\n| `ollama` | `--host`,默认 `http://127.0.0.1:11434` | 不需要 | `--model`,默认 `qwen3.5:4b` |\n\n如果有额外的敏感环境变量需要从 trace/report 里脱敏,可以用 `PICO_SECRET_ENV_NAMES` 配置逗号分隔的变量名,或启动时重复传 `--secret-env-name NAME`。\n\n### OpenAI 兼容接口\n\n如果要改用 OpenAI-compatible `/responses` 服务,显式传 `--provider openai`:\n\n```bash\nuv run pico --provider openai\n```\n\n默认 OpenAI 兼容接口使用 right.codes 的 Codex endpoint:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://www.right.codes/codex/v1\"\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n也可以改成其他 OpenAI-compatible 服务:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://your-api.example/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n### Anthropic 兼容接口\n\n如果要改用 Anthropic-compatible 服务,显式传 `--provider anthropic`:\n\n```bash\nuv run pico --provider anthropic\n```\n\n默认 Anthropic 兼容接口使用 right.codes 的 Claude endpoint:\n\n```bash\nPICO_ANTHROPIC_API_BASE=\"https://www.right.codes/claude/v1\"\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\nPICO_ANTHROPIC_MODEL=\"claude-sonnet-4-6\"\n```\n\n如果你的服务端对多个兼容接口复用了同一套密钥,`pico` 也支持从 `PICO_ANTHROPIC_API_KEY` 回退到 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY` 或 `OPENAI_API_KEY`。\n\n### Ollama\n\n如果要改用本地 Ollama,显式传 `--provider ollama`:\n\n```bash\nollama serve\nollama pull qwen3.5:4b\nuv run pico --provider ollama --model qwen3.5:4b\n```\n\n## 常用交互命令\n\n- `/help`:查看内置命令\n- `/memory`:查看提炼后的工作记忆\n- `/session`:查看当前会话文件路径\n- `/reset`:清空当前会话状态\n- `/exit` 或 `/quit`:退出 REPL\n\n## 安全与持久化\n\n`pico` 不会默认把所有动作都放开。像 shell 执行、文件写入这类高风险操作,会受审批模式控制:\n\n- `--approval ask`\n- `--approval auto`\n- `--approval never`\n\n每次运行结束后,都会在 `.pico/runs/<run_id>/` 下写出这些文件:\n\n- `task_state.json`\n- `trace.jsonl`\n- `report.json`\n\n这些内容默认只保存在本地,不需要跟仓库一起提交。\n\n## 开发\n\n常用本地检查:\n\n```bash\nuv run pytest tests -q\nuv run ruff check pico tests scripts\n```\n\n内部代码现在按较轻的边界拆分:`pico/evaluation/` 放 benchmark 和 metrics,`pico/providers/` 放模型 provider client,`pico/features/` 放可选运行时能力。新代码应直接使用这些包路径;旧的 `pico.evaluator`、`pico.metrics`、`pico.models` 和 `pico.memory` import 不再作为公共入口保留。\n"}, "9741eec8e4fa35e1b912db2e474f7b06ace33408": {"t": 1785767258.9165025, "n": 6315, "h": "9fd93784c23d85af", "c": "# pico\n\n`pico` 是一个面向代码仓库的轻量本地 coding agent。它直接跑在终端里,先看当前工作区,再用一组受约束的工具去读文件、改文件、跑命令,并把会话状态保存在本地 `.pico/` 目录里。\n\n它更像一个能在仓库里持续工作的命令行助手,不是纯聊天窗口。你可以拿它做代码排查、测试修复、仓库分析,或者让它在当前项目里执行一次性的工程任务。\n\n## 适合做什么\n\n- 在本地仓库里排查测试失败\n- 读取当前代码结构并给出修改建议\n- 基于现有文件做小步迭代,而不是脱离仓库空想\n- 在会话中保留上下文,支持继续上一次工作\n\n## 主要特性\n\n- 包名是 `pico`\n- CLI 命令是 `pico`\n- 模块入口是 `python -m pico`\n- 会话保存在 `.pico/sessions/`\n- 每次运行的工件保存在 `.pico/runs/<run_id>/`\n- 支持四类模型后端:\n - Ollama\n - OpenAI 兼容 Responses API\n - Anthropic 兼容 Messages API\n - DeepSeek Anthropic 兼容 API\n\n## 使用截图\n\nCLI 帮助信息:\n\n\n\n启动界面:\n\n\n\nREPL 内置命令与会话路径:\n\n\n\n## 安装\n\n需要 Python 3.10+。\n\n如果你用 `uv`,直接安装依赖:\n\n```bash\nuv sync\n```\n\n如果你已经在自己的 Python 环境里工作,也可以直接装成可编辑模式:\n\n```bash\npip install -e .\n```\n\n## 快速开始\n\n在当前仓库里启动交互模式。默认 provider 是 DeepSeek:\n\n```bash\nuv run pico\n```\n\n指定另一个工作目录:\n\n```bash\nuv run pico --cwd /path/to/repo\n```\n\n直接跑一次性任务:\n\n```bash\nuv run pico \"inspect the test failures and propose a fix\"\n```\n\n如果当前环境已经安装过包,也可以直接这样启动:\n\n```bash\npython -m pico\n```\n\n## 模型后端\n\nPico 启动时会读取项目根目录的 `.env`。本地真实 key 放在 `.env`,仓库只保留 `.env.example`。配置优先级是:\n\n```text\n显式 CLI 参数 > .env 里的 PICO_* 变量 > 旧环境变量 > 代码默认值\n```\n\nProvider 选择的具体顺序是:\n\n```text\n--provider > PICO_PROVIDER > 代码默认 deepseek\n```\n\n不传 `--provider` 且没有 `PICO_PROVIDER` 时默认使用 `deepseek`。这是推荐配置路径:DeepSeek 的 Anthropic-compatible endpoint 比本地 Ollama 更少依赖本机模型环境,也比 OpenAI-compatible/Anthropic-compatible 代理少一层默认 gateway 假设。其他 provider 仍然保留,可以在 `.env` 里写 `PICO_PROVIDER=openai`、`PICO_PROVIDER=anthropic`、`PICO_PROVIDER=ollama`,也可以显式传 `--provider openai`、`--provider anthropic` 或 `--provider ollama`。\n\n`.env` 会在构建 provider client 前加载,并覆盖当前进程里的同名环境变量。模型名和 base URL 可以通过 `--model`、`--base-url` 临时覆盖;API key 只从环境变量读取。\n\n本地第一次配置:\n\n```bash\ncp .env.example .env\n```\n\n然后把要使用的 provider key 填进去。`.env` 已经被 `.gitignore` 忽略,不要提交真实 key。\n\n### 推荐配置:DeepSeek\n\n最小配置只需要 key:\n\n```bash\nPICO_DEEPSEEK_API_KEY=\"your-api-key\"\n```\n\n默认模型和接口是:\n\n```bash\nPICO_DEEPSEEK_API_BASE=\"https://api.deepseek.com/anthropic\"\nPICO_DEEPSEEK_MODEL=\"deepseek-v4-pro\"\n```\n\n所以常规情况下 `.env` 里只填 `PICO_DEEPSEEK_API_KEY` 就能直接启动:\n\n```bash\nuv run pico\n```\n\n如果你需要临时切模型或代理地址,不必改 `.env`,可以直接覆盖:\n\n```bash\nuv run pico --model deepseek-v4-pro --base-url https://api.deepseek.com/anthropic\n```\n\nDeepSeek 当前走 Anthropic-compatible Messages API,所以 runtime 里复用的是 Anthropic-compatible client;这只影响 HTTP 协议,不影响 CLI 用法。\n\n### 可选配置:right.codes\n\nright.codes 在 Pico 里有两条可选 provider 路径:\n\n- `--provider openai`:走 OpenAI-compatible `/responses`,默认 base URL 是 `https://www.right.codes/codex/v1`,默认模型是 `gpt-5.4`\n- `--provider anthropic`:走 Anthropic-compatible `/messages`,默认 base URL 是 `https://www.right.codes/claude/v1`,默认模型是 `claude-sonnet-4-6`\n\n如果 right.codes 给你的是一把共享 key,推荐只填这一项:\n\n```bash\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\n```\n\n然后按需要选择 provider:\n\n```bash\nuv run pico --provider openai\nuv run pico --provider anthropic\n```\n\n如果你想显式区分两条 provider 的 key,也可以分别配置:\n\n```bash\nPICO_OPENAI_API_KEY=\"your-right-codes-key-for-codex\"\nPICO_ANTHROPIC_API_KEY=\"your-right-codes-key-for-claude\"\n```\n\n不要在 `.env` 里写 `PICO_OPENAI_API_KEY=$PICO_RIGHT_CODES_API_KEY` 这种 shell 展开形式;Pico 的 `.env` 解析器只读取字面量,不展开变量引用。要么只写 `PICO_RIGHT_CODES_API_KEY`,要么把 key 字符串分别填到 provider-specific 变量里。\n\n如果请求 right.codes 返回 `API Key额度不足`,说明协议和 endpoint 已经打通,但当前 key 没有可用额度;换一把有额度的 key,或到 right.codes 后台处理额度。\n\n当前 provider 环境变量:\n\n| provider | base URL | API key | model |\n| --- | --- | --- | --- |\n| `deepseek` | `PICO_DEEPSEEK_API_BASE`,回退 `DEEPSEEK_API_BASE`,默认 `https://api.deepseek.com/anthropic` | `PICO_DEEPSEEK_API_KEY`,回退 `DEEPSEEK_API_KEY` | `PICO_DEEPSEEK_MODEL`,回退 `DEEPSEEK_MODEL`,默认 `deepseek-v4-pro` |\n| `openai` | `PICO_OPENAI_API_BASE`,回退 `OPENAI_API_BASE`,默认 `https://www.right.codes/codex/v1` | `PICO_OPENAI_API_KEY`,回退 `OPENAI_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_ANTHROPIC_API_KEY`、`ANTHROPIC_API_KEY` | `PICO_OPENAI_MODEL`,回退 `OPENAI_MODEL`,默认 `gpt-5.4` |\n| `anthropic` | `PICO_ANTHROPIC_API_BASE`,回退 `ANTHROPIC_API_BASE`,默认 `https://www.right.codes/claude/v1` | `PICO_ANTHROPIC_API_KEY`,回退 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY`、`OPENAI_API_KEY` | `PICO_ANTHROPIC_MODEL`,回退 `ANTHROPIC_MODEL`,默认 `claude-sonnet-4-6` |\n| `ollama` | `--host`,默认 `http://127.0.0.1:11434` | 不需要 | `--model`,默认 `qwen3.5:4b` |\n\n如果有额外的敏感环境变量需要从 trace/report 里脱敏,可以用 `PICO_SECRET_ENV_NAMES` 配置逗号分隔的变量名,或启动时重复传 `--secret-env-name NAME`。\n\n### OpenAI 兼容接口\n\n如果要改用 OpenAI-compatible `/responses` 服务,显式传 `--provider openai`:\n\n```bash\nuv run pico --provider openai\n```\n\n默认 OpenAI 兼容接口使用 right.codes 的 Codex endpoint:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://www.right.codes/codex/v1\"\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n也可以改成其他 OpenAI-compatible 服务:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://your-api.example/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n### Anthropic 兼容接口\n\n如果要改用 Anthropic-compatible 服务,显式传 `--provider anthropic`:\n\n```bash\nuv run pico --provider anthropic\n```\n\n默认 Anthropic 兼容接口使用 right.codes 的 Claude endpoint:\n\n```bash\nPICO_ANTHROPIC_API_BASE=\"https://www.right.codes/claude/v1\"\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\nPICO_ANTHROPIC_MODEL=\"claude-sonnet-4-6\"\n```\n\n如果你的服务端对多个兼容接口复用了同一套密钥,`pico` 也支持从 `PICO_ANTHROPIC_API_KEY` 回退到 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY` 或 `OPENAI_API_KEY`。\n\n### Ollama\n\n如果要改用本地 Ollama,显式传 `--provider ollama`:\n\n```bash\nollama serve\nollama pull qwen3.5:4b\nuv run pico --provider ollama --model qwen3.5:4b\n```\n\n## 常用交互命令\n\n- `/help`:查看内置命令\n- `/memory`:查看提炼后的工作记忆\n- `/session`:查看当前会话文件路径\n- `/reset`:清空当前会话状态\n- `/exit` 或 `/quit`:退出 REPL\n\n## 安全与持久化\n\n`pico` 不会默认把所有动作都放开。像 shell 执行、文件写入这类高风险操作,会受审批模式控制:\n\n- `--approval ask`\n- `--approval auto`\n- `--approval never`\n\n每次运行结束后,都会在 `.pico/runs/<run_id>/` 下写出这些文件:\n\n- `task_state.json`\n- `trace.jsonl`\n- `report.json`\n\n这些内容默认只保存在本地,不需要跟仓库一起提交。\n\n## 开发\n\n常用本地检查:\n\n```bash\nuv run pytest tests -q\nuv run ruff check pico tests scripts\n```\n\n内部代码现在按较轻的边界拆分:`pico/evaluation/` 放 benchmark 和 metrics,`pico/providers/` 放模型 provider client,`pico/features/` 放可选运行时能力。新代码应直接使用这些包路径;旧的 `pico.evaluator`、`pico.metrics`、`pico.models` 和 `pico.memory` import 不再作为公共入口保留。\n"}, "9dd7bfa15b9c79f1d5082c8989b1d7e887205a24": {"t": 1785767260.116158, "n": 6132, "h": "ab286896de93b454", "c": "# pico\n\n`pico` 是一个面向代码仓库的轻量本地 coding agent。它直接跑在终端里,先看当前工作区,再用一组受约束的工具去读文件、改文件、跑命令,并把会话状态保存在本地 `.pico/` 目录里。\n\n它更像一个能在仓库里持续工作的命令行助手,不是纯聊天窗口。你可以拿它做代码排查、测试修复、仓库分析,或者让它在当前项目里执行一次性的工程任务。\n\n## 适合做什么\n\n- 在本地仓库里排查测试失败\n- 读取当前代码结构并给出修改建议\n- 基于现有文件做小步迭代,而不是脱离仓库空想\n- 在会话中保留上下文,支持继续上一次工作\n\n## 主要特性\n\n- 包名是 `pico`\n- CLI 命令是 `pico`\n- 模块入口是 `python -m pico`\n- 会话保存在 `.pico/sessions/`\n- 每次运行的工件保存在 `.pico/runs/<run_id>/`\n- 支持四类模型后端:\n - Ollama\n - OpenAI 兼容 Responses API\n - Anthropic 兼容 Messages API\n - DeepSeek Anthropic 兼容 API\n\n## 使用截图\n\nCLI 帮助信息:\n\n\n\n启动界面:\n\n\n\nREPL 内置命令与会话路径:\n\n\n\n## 安装\n\n需要 Python 3.10+。\n\n如果你用 `uv`,直接安装依赖:\n\n```bash\nuv sync\n```\n\n如果你已经在自己的 Python 环境里工作,也可以直接装成可编辑模式:\n\n```bash\npip install -e .\n```\n\n## 快速开始\n\n在当前仓库里启动交互模式。默认 provider 是 DeepSeek:\n\n```bash\nuv run pico\n```\n\n指定另一个工作目录:\n\n```bash\nuv run pico --cwd /path/to/repo\n```\n\n直接跑一次性任务:\n\n```bash\nuv run pico \"inspect the test failures and propose a fix\"\n```\n\n如果当前环境已经安装过包,也可以直接这样启动:\n\n```bash\npython -m pico\n```\n\n## 模型后端\n\nPico 启动时会读取项目根目录的 `.env`。本地真实 key 放在 `.env`,仓库只保留 `.env.example`。配置优先级是:\n\n```text\n显式 CLI 参数 > .env 里的 PICO_* 变量 > 旧环境变量 > 代码默认值\n```\n\n不传 `--provider` 时默认使用 `deepseek`。这是推荐配置路径:DeepSeek 的 Anthropic-compatible endpoint 比本地 Ollama 更少依赖本机模型环境,也比 OpenAI-compatible/Anthropic-compatible 代理少一层默认 gateway 假设。其他 provider 仍然保留,可以显式传 `--provider openai`、`--provider anthropic` 或 `--provider ollama`。\n\n`.env` 会在构建 provider client 前加载,并覆盖当前进程里的同名环境变量。模型名和 base URL 可以通过 `--model`、`--base-url` 临时覆盖;API key 只从环境变量读取。\n\n本地第一次配置:\n\n```bash\ncp .env.example .env\n```\n\n然后把要使用的 provider key 填进去。`.env` 已经被 `.gitignore` 忽略,不要提交真实 key。\n\n### 推荐配置:DeepSeek\n\n最小配置只需要 key:\n\n```bash\nPICO_DEEPSEEK_API_KEY=\"your-api-key\"\n```\n\n默认模型和接口是:\n\n```bash\nPICO_DEEPSEEK_API_BASE=\"https://api.deepseek.com/anthropic\"\nPICO_DEEPSEEK_MODEL=\"deepseek-v4-pro\"\n```\n\n所以常规情况下 `.env` 里只填 `PICO_DEEPSEEK_API_KEY` 就能直接启动:\n\n```bash\nuv run pico\n```\n\n如果你需要临时切模型或代理地址,不必改 `.env`,可以直接覆盖:\n\n```bash\nuv run pico --model deepseek-v4-pro --base-url https://api.deepseek.com/anthropic\n```\n\nDeepSeek 当前走 Anthropic-compatible Messages API,所以 runtime 里复用的是 Anthropic-compatible client;这只影响 HTTP 协议,不影响 CLI 用法。\n\n### 可选配置:right.codes\n\nright.codes 在 Pico 里有两条可选 provider 路径:\n\n- `--provider openai`:走 OpenAI-compatible `/responses`,默认 base URL 是 `https://www.right.codes/codex/v1`,默认模型是 `gpt-5.4`\n- `--provider anthropic`:走 Anthropic-compatible `/messages`,默认 base URL 是 `https://www.right.codes/claude/v1`,默认模型是 `claude-sonnet-4-6`\n\n如果 right.codes 给你的是一把共享 key,推荐只填这一项:\n\n```bash\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\n```\n\n然后按需要选择 provider:\n\n```bash\nuv run pico --provider openai\nuv run pico --provider anthropic\n```\n\n如果你想显式区分两条 provider 的 key,也可以分别配置:\n\n```bash\nPICO_OPENAI_API_KEY=\"your-right-codes-key-for-codex\"\nPICO_ANTHROPIC_API_KEY=\"your-right-codes-key-for-claude\"\n```\n\n不要在 `.env` 里写 `PICO_OPENAI_API_KEY=$PICO_RIGHT_CODES_API_KEY` 这种 shell 展开形式;Pico 的 `.env` 解析器只读取字面量,不展开变量引用。要么只写 `PICO_RIGHT_CODES_API_KEY`,要么把 key 字符串分别填到 provider-specific 变量里。\n\n如果请求 right.codes 返回 `API Key额度不足`,说明协议和 endpoint 已经打通,但当前 key 没有可用额度;换一把有额度的 key,或到 right.codes 后台处理额度。\n\n当前 provider 环境变量:\n\n| provider | base URL | API key | model |\n| --- | --- | --- | --- |\n| `deepseek` | `PICO_DEEPSEEK_API_BASE`,回退 `DEEPSEEK_API_BASE`,默认 `https://api.deepseek.com/anthropic` | `PICO_DEEPSEEK_API_KEY`,回退 `DEEPSEEK_API_KEY` | `PICO_DEEPSEEK_MODEL`,回退 `DEEPSEEK_MODEL`,默认 `deepseek-v4-pro` |\n| `openai` | `PICO_OPENAI_API_BASE`,回退 `OPENAI_API_BASE`,默认 `https://www.right.codes/codex/v1` | `PICO_OPENAI_API_KEY`,回退 `OPENAI_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_ANTHROPIC_API_KEY`、`ANTHROPIC_API_KEY` | `PICO_OPENAI_MODEL`,回退 `OPENAI_MODEL`,默认 `gpt-5.4` |\n| `anthropic` | `PICO_ANTHROPIC_API_BASE`,回退 `ANTHROPIC_API_BASE`,默认 `https://www.right.codes/claude/v1` | `PICO_ANTHROPIC_API_KEY`,回退 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY`、`OPENAI_API_KEY` | `PICO_ANTHROPIC_MODEL`,回退 `ANTHROPIC_MODEL`,默认 `claude-sonnet-4-6` |\n| `ollama` | `--host`,默认 `http://127.0.0.1:11434` | 不需要 | `--model`,默认 `qwen3.5:4b` |\n\n如果有额外的敏感环境变量需要从 trace/report 里脱敏,可以用 `PICO_SECRET_ENV_NAMES` 配置逗号分隔的变量名,或启动时重复传 `--secret-env-name NAME`。\n\n### OpenAI 兼容接口\n\n如果要改用 OpenAI-compatible `/responses` 服务,显式传 `--provider openai`:\n\n```bash\nuv run pico --provider openai\n```\n\n默认 OpenAI 兼容接口使用 right.codes 的 Codex endpoint:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://www.right.codes/codex/v1\"\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n也可以改成其他 OpenAI-compatible 服务:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://your-api.example/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n### Anthropic 兼容接口\n\n如果要改用 Anthropic-compatible 服务,显式传 `--provider anthropic`:\n\n```bash\nuv run pico --provider anthropic\n```\n\n默认 Anthropic 兼容接口使用 right.codes 的 Claude endpoint:\n\n```bash\nPICO_ANTHROPIC_API_BASE=\"https://www.right.codes/claude/v1\"\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\nPICO_ANTHROPIC_MODEL=\"claude-sonnet-4-6\"\n```\n\n如果你的服务端对多个兼容接口复用了同一套密钥,`pico` 也支持从 `PICO_ANTHROPIC_API_KEY` 回退到 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY` 或 `OPENAI_API_KEY`。\n\n### Ollama\n\n如果要改用本地 Ollama,显式传 `--provider ollama`:\n\n```bash\nollama serve\nollama pull qwen3.5:4b\nuv run pico --provider ollama --model qwen3.5:4b\n```\n\n## 常用交互命令\n\n- `/help`:查看内置命令\n- `/memory`:查看提炼后的工作记忆\n- `/session`:查看当前会话文件路径\n- `/reset`:清空当前会话状态\n- `/exit` 或 `/quit`:退出 REPL\n\n## 安全与持久化\n\n`pico` 不会默认把所有动作都放开。像 shell 执行、文件写入这类高风险操作,会受审批模式控制:\n\n- `--approval ask`\n- `--approval auto`\n- `--approval never`\n\n每次运行结束后,都会在 `.pico/runs/<run_id>/` 下写出这些文件:\n\n- `task_state.json`\n- `trace.jsonl`\n- `report.json`\n\n这些内容默认只保存在本地,不需要跟仓库一起提交。\n\n## 开发\n\n常用本地检查:\n\n```bash\nuv run pytest tests -q\nuv run ruff check pico tests scripts\n```\n\n内部代码现在按较轻的边界拆分:`pico/evaluation/` 放 benchmark 和 metrics,`pico/providers/` 放模型 provider client,`pico/features/` 放可选运行时能力。新代码应直接使用这些包路径;旧的 `pico.evaluator`、`pico.metrics`、`pico.models` 和 `pico.memory` import 不再作为公共入口保留。\n"}, "e7cc1bffa1cdf83ad7cdd06e51c417c32a3b1cbf": {"t": 1785767261.3127604, "n": 6116, "h": "4501ff181ed6ba51", "c": "# pico\n\n`pico` 是一个面向代码仓库的轻量本地 coding agent。它直接跑在终端里,先看当前工作区,再用一组受约束的工具去读文件、改文件、跑命令,并把会话状态保存在本地 `.pico/` 目录里。\n\n它更像一个能在仓库里持续工作的命令行助手,不是纯聊天窗口。你可以拿它做代码排查、测试修复、仓库分析,或者让它在当前项目里执行一次性的工程任务。\n\n## 适合做什么\n\n- 在本地仓库里排查测试失败\n- 读取当前代码结构并给出修改建议\n- 基于现有文件做小步迭代,而不是脱离仓库空想\n- 在会话中保留上下文,支持继续上一次工作\n\n## 主要特性\n\n- 包名是 `pico`\n- CLI 命令是 `pico`\n- 模块入口是 `python -m pico`\n- 会话保存在 `.pico/sessions/`\n- 每次运行的工件保存在 `.pico/runs/<run_id>/`\n- 支持四类模型后端:\n - Ollama\n - OpenAI 兼容 Responses API\n - Anthropic 兼容 Messages API\n - DeepSeek Anthropic 兼容 API\n\n## 使用截图\n\nCLI 帮助信息:\n\n\n\n启动界面:\n\n\n\nREPL 内置命令与会话路径:\n\n\n\n## 安装\n\n需要 Python 3.10+。\n\n如果你用 `uv`,直接安装依赖:\n\n```bash\nuv sync\n```\n\n如果你已经在自己的 Python 环境里工作,也可以直接装成可编辑模式:\n\n```bash\npip install -e .\n```\n\n## 快速开始\n\n在当前仓库里启动交互模式。默认 provider 是 DeepSeek:\n\n```bash\nuv run pico\n```\n\n指定另一个工作目录:\n\n```bash\nuv run pico --cwd /path/to/repo\n```\n\n直接跑一次性任务:\n\n```bash\nuv run pico \"inspect the test failures and propose a fix\"\n```\n\n如果当前环境已经安装过包,也可以直接这样启动:\n\n```bash\npython -m pico\n```\n\n## 模型后端\n\nPico 启动时会读取项目根目录的 `.env`。本地真实 key 放在 `.env`,仓库只保留 `.env.example`。配置优先级是:\n\n```text\n显式 CLI 参数 > .env 里的 PICO_* 变量 > 旧环境变量 > 代码默认值\n```\n\n不传 `--provider` 时默认使用 `deepseek`。这是推荐配置路径:DeepSeek 的 Anthropic-compatible endpoint 比本地 Ollama 更少依赖本机模型环境,也比 OpenAI-compatible/Anthropic-compatible 代理少一层默认 gateway 假设。其他 provider 仍然保留,可以显式传 `--provider openai`、`--provider anthropic` 或 `--provider ollama`。\n\n`.env` 会在构建 provider client 前加载,并覆盖当前进程里的同名环境变量。模型名和 base URL 可以通过 `--model`、`--base-url` 临时覆盖;API key 只从环境变量读取。\n\n本地第一次配置:\n\n```bash\ncp .env.example .env\n```\n\n然后把要使用的 provider key 填进去。`.env` 已经被 `.gitignore` 忽略,不要提交真实 key。\n\n### 推荐配置:DeepSeek\n\n最小配置只需要 key:\n\n```bash\nPICO_DEEPSEEK_API_KEY=\"your-api-key\"\n```\n\n默认模型和接口是:\n\n```bash\nPICO_DEEPSEEK_API_BASE=\"https://api.deepseek.com/anthropic\"\nPICO_DEEPSEEK_MODEL=\"deepseek-v4-pro\"\n```\n\n所以常规情况下 `.env` 里只填 `PICO_DEEPSEEK_API_KEY` 就能直接启动:\n\n```bash\nuv run pico\n```\n\n如果你需要临时切模型或代理地址,不必改 `.env`,可以直接覆盖:\n\n```bash\nuv run pico --model deepseek-v4-pro --base-url https://api.deepseek.com/anthropic\n```\n\nDeepSeek 当前走 Anthropic-compatible Messages API,所以 runtime 里复用的是 Anthropic-compatible client;这只影响 HTTP 协议,不影响 CLI 用法。\n\n### 可选配置:right.codes\n\nright.codes 在 Pico 里有两条可选 provider 路径:\n\n- `--provider openai`:走 OpenAI-compatible `/responses`,默认 base URL 是 `https://www.right.codes/codex/v1`,默认模型是 `gpt-5.4`\n- `--provider anthropic`:走 Anthropic-compatible `/messages`,默认 base URL 是 `https://www.right.codes/claude/v1`,默认模型是 `claude-sonnet-4-6`\n\n如果 right.codes 给你的是一把共享 key,推荐只填这一项:\n\n```bash\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\n```\n\n然后按需要选择 provider:\n\n```bash\nuv run pico --provider openai\nuv run pico --provider anthropic\n```\n\n如果你想显式区分两条 provider 的 key,也可以分别配置:\n\n```bash\nPICO_OPENAI_API_KEY=\"your-right-codes-key-for-codex\"\nPICO_ANTHROPIC_API_KEY=\"your-right-codes-key-for-claude\"\n```\n\n不要在 `.env` 里写 `PICO_OPENAI_API_KEY=$PICO_RIGHT_CODES_API_KEY` 这种 shell 展开形式;Pico 的 `.env` 解析器只读取字面量,不展开变量引用。要么只写 `PICO_RIGHT_CODES_API_KEY`,要么把 key 字符串分别填到 provider-specific 变量里。\n\n如果请求 right.codes 返回 `API Key额度不足`,说明协议和 endpoint 已经打通,但当前 key 没有可用额度;换一把有额度的 key,或到 right.codes 后台处理额度。\n\n当前 provider 环境变量:\n\n| provider | base URL | API key | model |\n| --- | --- | --- | --- |\n| `deepseek` | `PICO_DEEPSEEK_API_BASE`,回退 `DEEPSEEK_API_BASE`,默认 `https://api.deepseek.com/anthropic` | `PICO_DEEPSEEK_API_KEY`,回退 `DEEPSEEK_API_KEY` | `PICO_DEEPSEEK_MODEL`,回退 `DEEPSEEK_MODEL`,默认 `deepseek-v4-pro` |\n| `openai` | `PICO_OPENAI_API_BASE`,回退 `OPENAI_API_BASE`,默认 `https://www.right.codes/codex/v1` | `PICO_OPENAI_API_KEY`,回退 `OPENAI_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_ANTHROPIC_API_KEY`、`ANTHROPIC_API_KEY` | `PICO_OPENAI_MODEL`,回退 `OPENAI_MODEL`,默认 `gpt-5.4` |\n| `anthropic` | `PICO_ANTHROPIC_API_BASE`,回退 `ANTHROPIC_API_BASE`,默认 `https://www.right.codes/claude/v1` | `PICO_ANTHROPIC_API_KEY`,回退 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY`、`OPENAI_API_KEY` | `PICO_ANTHROPIC_MODEL`,回退 `ANTHROPIC_MODEL`,默认 `claude-sonnet-4-6` |\n| `ollama` | `--host`,默认 `http://127.0.0.1:11434` | 不需要 | `--model`,默认 `qwen3.5:4b` |\n\n如果有额外的敏感环境变量需要从 trace/report 里脱敏,可以用 `PICO_SECRET_ENV_NAMES` 配置逗号分隔的变量名,或启动时重复传 `--secret-env-name NAME`。\n\n### OpenAI 兼容接口\n\n如果要改用 OpenAI-compatible `/responses` 服务,显式传 `--provider openai`:\n\n```bash\nuv run pico --provider openai\n```\n\n默认 OpenAI 兼容接口使用 right.codes 的 Codex endpoint:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://www.right.codes/codex/v1\"\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n也可以改成其他 OpenAI-compatible 服务:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://your-api.example/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n### Anthropic 兼容接口\n\n如果要改用 Anthropic-compatible 服务,显式传 `--provider anthropic`:\n\n```bash\nuv run pico --provider anthropic\n```\n\n默认 Anthropic 兼容接口使用 right.codes 的 Claude endpoint:\n\n```bash\nPICO_ANTHROPIC_API_BASE=\"https://www.right.codes/claude/v1\"\nPICO_RIGHT_CODES_API_KEY=\"your-right-codes-key\"\nPICO_ANTHROPIC_MODEL=\"claude-sonnet-4-6\"\n```\n\n如果你的服务端对多个兼容接口复用了同一套密钥,`pico` 也支持从 `PICO_ANTHROPIC_API_KEY` 回退到 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY` 或 `OPENAI_API_KEY`。\n\n### Ollama\n\n如果要改用本地 Ollama,显式传 `--provider ollama`:\n\n```bash\nollama serve\nollama pull qwen3.5:4b\nuv run pico --provider ollama --model qwen3.5:4b\n```\n\n## 常用交互命令\n\n- `/help`:查看内置命令\n- `/memory`:查看提炼后的工作记忆\n- `/session`:查看当前会话文件路径\n- `/reset`:清空当前会话状态\n- `/exit` 或 `/quit`:退出 REPL\n\n## 安全与持久化\n\n`pico` 不会默认把所有动作都放开。像 shell 执行、文件写入这类高风险操作,会受审批模式控制:\n\n- `--approval ask`\n- `--approval auto`\n- `--approval never`\n\n每次运行结束后,都会在 `.pico/runs/<run_id>/` 下写出这些文件:\n\n- `task_state.json`\n- `trace.jsonl`\n- `report.json`\n\n这些内容默认只保存在本地,不需要跟仓库一起提交。\n\n## 开发\n\n常用本地检查:\n\n```bash\nuv run pytest tests -q\nuv run ruff check pico tests scripts\n```\n\n内部代码现在按较轻的边界拆分:`pico/evaluation/` 放 benchmark 和 metrics,`pico/providers/` 放模型 provider client,`pico/features/` 放可选运行时能力。旧的 `pico.evaluator`、`pico.metrics`、`pico.models` 和 `pico.memory` import 仍保留为兼容入口。\n"}, "80be5e8712e8b7aca85a35f00697aeaa5134e799": {"t": 1785767262.5799253, "n": 5042, "h": "1dca2ff89db36987", "c": "# pico\n\n`pico` 是一个面向代码仓库的轻量本地 coding agent。它直接跑在终端里,先看当前工作区,再用一组受约束的工具去读文件、改文件、跑命令,并把会话状态保存在本地 `.pico/` 目录里。\n\n它更像一个能在仓库里持续工作的命令行助手,不是纯聊天窗口。你可以拿它做代码排查、测试修复、仓库分析,或者让它在当前项目里执行一次性的工程任务。\n\n## 适合做什么\n\n- 在本地仓库里排查测试失败\n- 读取当前代码结构并给出修改建议\n- 基于现有文件做小步迭代,而不是脱离仓库空想\n- 在会话中保留上下文,支持继续上一次工作\n\n## 主要特性\n\n- 包名是 `pico`\n- CLI 命令是 `pico`\n- 模块入口是 `python -m pico`\n- 会话保存在 `.pico/sessions/`\n- 每次运行的工件保存在 `.pico/runs/<run_id>/`\n- 支持四类模型后端:\n - Ollama\n - OpenAI 兼容 Responses API\n - Anthropic 兼容 Messages API\n - DeepSeek Anthropic 兼容 API\n\n## 使用截图\n\nCLI 帮助信息:\n\n\n\n启动界面:\n\n\n\nREPL 内置命令与会话路径:\n\n\n\n## 安装\n\n需要 Python 3.10+。\n\n如果你用 `uv`,直接安装依赖:\n\n```bash\nuv sync\n```\n\n如果你已经在自己的 Python 环境里工作,也可以直接装成可编辑模式:\n\n```bash\npip install -e .\n```\n\n## 快速开始\n\n在当前仓库里启动交互模式。默认 provider 是 DeepSeek:\n\n```bash\nuv run pico\n```\n\n指定另一个工作目录:\n\n```bash\nuv run pico --cwd /path/to/repo\n```\n\n直接跑一次性任务:\n\n```bash\nuv run pico \"inspect the test failures and propose a fix\"\n```\n\n如果当前环境已经安装过包,也可以直接这样启动:\n\n```bash\npython -m pico\n```\n\n## 模型后端\n\nPico 启动时会读取项目根目录的 `.env`。本地真实 key 放在 `.env`,仓库只保留 `.env.example`。配置优先级是:\n\n```text\n显式 CLI 参数 > .env 里的 PICO_* 变量 > 旧环境变量 > 代码默认值\n```\n\n不传 `--provider` 时默认使用 `deepseek`。这是推荐配置路径:DeepSeek 的 Anthropic-compatible endpoint 比本地 Ollama 更少依赖本机模型环境,也比 OpenAI-compatible/Anthropic-compatible 代理少一层默认 gateway 假设。其他 provider 仍然保留,可以显式传 `--provider openai`、`--provider anthropic` 或 `--provider ollama`。\n\n`.env` 会在构建 provider client 前加载,并覆盖当前进程里的同名环境变量。模型名和 base URL 可以通过 `--model`、`--base-url` 临时覆盖;API key 只从环境变量读取。\n\n本地第一次配置:\n\n```bash\ncp .env.example .env\n```\n\n然后把要使用的 provider key 填进去。`.env` 已经被 `.gitignore` 忽略,不要提交真实 key。\n\n### 推荐配置:DeepSeek\n\n最小配置只需要 key:\n\n```bash\nPICO_DEEPSEEK_API_KEY=\"your-api-key\"\n```\n\n默认模型和接口是:\n\n```bash\nPICO_DEEPSEEK_API_BASE=\"https://api.deepseek.com/anthropic\"\nPICO_DEEPSEEK_MODEL=\"deepseek-v4-pro\"\n```\n\n所以常规情况下 `.env` 里只填 `PICO_DEEPSEEK_API_KEY` 就能直接启动:\n\n```bash\nuv run pico\n```\n\n如果你需要临时切模型或代理地址,不必改 `.env`,可以直接覆盖:\n\n```bash\nuv run pico --model deepseek-v4-pro --base-url https://api.deepseek.com/anthropic\n```\n\nDeepSeek 当前走 Anthropic-compatible Messages API,所以 runtime 里复用的是 Anthropic-compatible client;这只影响 HTTP 协议,不影响 CLI 用法。\n\n当前 provider 环境变量:\n\n| provider | base URL | API key | model |\n| --- | --- | --- | --- |\n| `deepseek` | `PICO_DEEPSEEK_API_BASE`,回退 `DEEPSEEK_API_BASE`,默认 `https://api.deepseek.com/anthropic` | `PICO_DEEPSEEK_API_KEY`,回退 `DEEPSEEK_API_KEY` | `PICO_DEEPSEEK_MODEL`,回退 `DEEPSEEK_MODEL`,默认 `deepseek-v4-pro` |\n| `openai` | `PICO_OPENAI_API_BASE`,回退 `OPENAI_API_BASE`,默认 `https://www.right.codes/codex/v1` | `PICO_OPENAI_API_KEY`,回退 `OPENAI_API_KEY` | `PICO_OPENAI_MODEL`,回退 `OPENAI_MODEL`,默认 `gpt-5.4` |\n| `anthropic` | `PICO_ANTHROPIC_API_BASE`,回退 `ANTHROPIC_API_BASE`,默认 `https://www.right.codes/claude/v1` | `PICO_ANTHROPIC_API_KEY`,回退 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY`、`OPENAI_API_KEY` | `PICO_ANTHROPIC_MODEL`,回退 `ANTHROPIC_MODEL`,默认 `claude-sonnet-4-6` |\n| `ollama` | `--host`,默认 `http://127.0.0.1:11434` | 不需要 | `--model`,默认 `qwen3.5:4b` |\n\n如果有额外的敏感环境变量需要从 trace/report 里脱敏,可以用 `PICO_SECRET_ENV_NAMES` 配置逗号分隔的变量名,或启动时重复传 `--secret-env-name NAME`。\n\n### OpenAI 兼容接口\n\n如果要改用 OpenAI-compatible `/responses` 服务,显式传 `--provider openai`:\n\n```bash\nuv run pico --provider openai\n```\n\n默认 OpenAI 兼容接口使用 right.codes 的 Codex endpoint:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://www.right.codes/codex/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n也可以改成其他 OpenAI-compatible 服务:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://your-api.example/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n### Anthropic 兼容接口\n\n如果要改用 Anthropic-compatible 服务,显式传 `--provider anthropic`:\n\n```bash\nuv run pico --provider anthropic\n```\n\n默认 Anthropic 兼容接口使用 right.codes 的 Claude endpoint:\n\n```bash\nPICO_ANTHROPIC_API_BASE=\"https://www.right.codes/claude/v1\"\nPICO_ANTHROPIC_API_KEY=\"your-api-key\"\nPICO_ANTHROPIC_MODEL=\"claude-sonnet-4-6\"\n```\n\n如果你的服务端对多个兼容接口复用了同一套密钥,`pico` 也支持从 `PICO_ANTHROPIC_API_KEY` 回退到 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY` 或 `OPENAI_API_KEY`。\n\n### Ollama\n\n如果要改用本地 Ollama,显式传 `--provider ollama`:\n\n```bash\nollama serve\nollama pull qwen3.5:4b\nuv run pico --provider ollama --model qwen3.5:4b\n```\n\n## 常用交互命令\n\n- `/help`:查看内置命令\n- `/memory`:查看提炼后的工作记忆\n- `/session`:查看当前会话文件路径\n- `/reset`:清空当前会话状态\n- `/exit` 或 `/quit`:退出 REPL\n\n## 安全与持久化\n\n`pico` 不会默认把所有动作都放开。像 shell 执行、文件写入这类高风险操作,会受审批模式控制:\n\n- `--approval ask`\n- `--approval auto`\n- `--approval never`\n\n每次运行结束后,都会在 `.pico/runs/<run_id>/` 下写出这些文件:\n\n- `task_state.json`\n- `trace.jsonl`\n- `report.json`\n\n这些内容默认只保存在本地,不需要跟仓库一起提交。\n\n## 开发\n\n常用本地检查:\n\n```bash\nuv run pytest tests -q\nuv run ruff check pico tests scripts\n```\n\n内部代码现在按较轻的边界拆分:`pico/evaluation/` 放 benchmark 和 metrics,`pico/providers/` 放模型 provider client,`pico/features/` 放可选运行时能力。旧的 `pico.evaluator`、`pico.metrics`、`pico.models` 和 `pico.memory` import 仍保留为兼容入口。\n"}, "d4a6d93d43a2ff9fd153d0e63aed50dedd55861c": {"t": 1785767264.071494, "n": 4578, "h": "b2850777e2a6b504", "c": "# pico\n\n`pico` 是一个面向代码仓库的轻量本地 coding agent。它直接跑在终端里,先看当前工作区,再用一组受约束的工具去读文件、改文件、跑命令,并把会话状态保存在本地 `.pico/` 目录里。\n\n它更像一个能在仓库里持续工作的命令行助手,不是纯聊天窗口。你可以拿它做代码排查、测试修复、仓库分析,或者让它在当前项目里执行一次性的工程任务。\n\n## 适合做什么\n\n- 在本地仓库里排查测试失败\n- 读取当前代码结构并给出修改建议\n- 基于现有文件做小步迭代,而不是脱离仓库空想\n- 在会话中保留上下文,支持继续上一次工作\n\n## 主要特性\n\n- 包名是 `pico`\n- CLI 命令是 `pico`\n- 模块入口是 `python -m pico`\n- 会话保存在 `.pico/sessions/`\n- 每次运行的工件保存在 `.pico/runs/<run_id>/`\n- 支持四类模型后端:\n - Ollama\n - OpenAI 兼容 Responses API\n - Anthropic 兼容 Messages API\n - DeepSeek Anthropic 兼容 API\n\n## 使用截图\n\nCLI 帮助信息:\n\n\n\n启动界面:\n\n\n\nREPL 内置命令与会话路径:\n\n\n\n## 安装\n\n需要 Python 3.10+。\n\n如果你用 `uv`,直接安装依赖:\n\n```bash\nuv sync\n```\n\n如果你已经在自己的 Python 环境里工作,也可以直接装成可编辑模式:\n\n```bash\npip install -e .\n```\n\n## 快速开始\n\n在当前仓库里启动交互模式。当前推荐使用 DeepSeek:\n\n```bash\nuv run pico --provider deepseek\n```\n\n指定另一个工作目录:\n\n```bash\nuv run pico --cwd /path/to/repo\n```\n\n直接跑一次性任务:\n\n```bash\nuv run pico --provider deepseek \"inspect the test failures and propose a fix\"\n```\n\n如果当前环境已经安装过包,也可以直接这样启动:\n\n```bash\npython -m pico --provider deepseek\n```\n\n## 模型后端\n\nPico 启动时会读取项目根目录的 `.env`。本地真实 key 放在 `.env`,仓库只保留 `.env.example`。配置优先级是:\n\n```text\n显式 CLI 参数 > .env 里的 PICO_* 变量 > 旧环境变量 > 代码默认值\n```\n\n不传 `--provider` 时默认使用 `openai`。如果要用 DeepSeek、Anthropic 或 Ollama,需要显式传 `--provider deepseek`、`--provider anthropic` 或 `--provider ollama`。\n\n`.env` 会在构建 provider client 前加载,并覆盖当前进程里的同名环境变量。模型名和 base URL 可以通过 `--model`、`--base-url` 临时覆盖;API key 只从环境变量读取。\n\n本地第一次配置:\n\n```bash\ncp .env.example .env\n```\n\n然后把要使用的 provider key 填进去。`.env` 已经被 `.gitignore` 忽略,不要提交真实 key。\n\n当前 provider 环境变量:\n\n| provider | base URL | API key | model |\n| --- | --- | --- | --- |\n| `openai` | `PICO_OPENAI_API_BASE`,回退 `OPENAI_API_BASE`,默认 `https://www.right.codes/codex/v1` | `PICO_OPENAI_API_KEY`,回退 `OPENAI_API_KEY` | `PICO_OPENAI_MODEL`,回退 `OPENAI_MODEL`,默认 `gpt-5.4` |\n| `anthropic` | `PICO_ANTHROPIC_API_BASE`,回退 `ANTHROPIC_API_BASE`,默认 `https://www.right.codes/claude/v1` | `PICO_ANTHROPIC_API_KEY`,回退 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY`、`OPENAI_API_KEY` | `PICO_ANTHROPIC_MODEL`,回退 `ANTHROPIC_MODEL`,默认 `claude-sonnet-4-6` |\n| `deepseek` | `PICO_DEEPSEEK_API_BASE`,回退 `DEEPSEEK_API_BASE`,默认 `https://api.deepseek.com/anthropic` | `PICO_DEEPSEEK_API_KEY`,回退 `DEEPSEEK_API_KEY` | `PICO_DEEPSEEK_MODEL`,回退 `DEEPSEEK_MODEL`,默认 `deepseek-v4-pro` |\n| `ollama` | `--host`,默认 `http://127.0.0.1:11434` | 不需要 | `--model`,默认 `qwen3.5:4b` |\n\n如果有额外的敏感环境变量需要从 trace/report 里脱敏,可以用 `PICO_SECRET_ENV_NAMES` 配置逗号分隔的变量名,或启动时重复传 `--secret-env-name NAME`。\n\n### Ollama\n\n```bash\nollama serve\nollama pull qwen3.5:4b\nuv run pico --provider ollama --model qwen3.5:4b\n```\n\n### OpenAI 兼容接口\n\n默认 OpenAI 兼容接口使用 right.codes 的 Codex endpoint:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://www.right.codes/codex/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n也可以改成其他 OpenAI-compatible 服务:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://your-api.example/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n```bash\nuv run pico --provider openai\n```\n\n### Anthropic 兼容接口\n\n默认 Anthropic 兼容接口使用 right.codes 的 Claude endpoint:\n\n```bash\nPICO_ANTHROPIC_API_BASE=\"https://www.right.codes/claude/v1\"\nPICO_ANTHROPIC_API_KEY=\"your-api-key\"\nPICO_ANTHROPIC_MODEL=\"claude-sonnet-4-6\"\n```\n\n```bash\nuv run pico --provider anthropic\n```\n\n如果你的服务端对多个兼容接口复用了同一套密钥,`pico` 也支持从 `PICO_ANTHROPIC_API_KEY` 回退到 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY` 或 `OPENAI_API_KEY`。\n\n### DeepSeek\n\n```bash\nPICO_DEEPSEEK_API_KEY=\"your-api-key\"\nPICO_DEEPSEEK_MODEL=\"deepseek-v4-pro\"\n```\n\n```bash\nuv run pico --provider deepseek\n```\n\n默认 DeepSeek base URL 是 `https://api.deepseek.com/anthropic`,走 DeepSeek 的 Anthropic 兼容接口。如果需要改到代理服务,可以设置 `PICO_DEEPSEEK_API_BASE` 或启动时传 `--base-url`。\n\n## 常用交互命令\n\n- `/help`:查看内置命令\n- `/memory`:查看提炼后的工作记忆\n- `/session`:查看当前会话文件路径\n- `/reset`:清空当前会话状态\n- `/exit` 或 `/quit`:退出 REPL\n\n## 安全与持久化\n\n`pico` 不会默认把所有动作都放开。像 shell 执行、文件写入这类高风险操作,会受审批模式控制:\n\n- `--approval ask`\n- `--approval auto`\n- `--approval never`\n\n每次运行结束后,都会在 `.pico/runs/<run_id>/` 下写出这些文件:\n\n- `task_state.json`\n- `trace.jsonl`\n- `report.json`\n\n这些内容默认只保存在本地,不需要跟仓库一起提交。\n\n## 开发\n\n常用本地检查:\n\n```bash\nuv run pytest tests -q\nuv run ruff check pico tests scripts\n```\n\n内部代码现在按较轻的边界拆分:`pico/evaluation/` 放 benchmark 和 metrics,`pico/providers/` 放模型 provider client,`pico/features/` 放可选运行时能力。旧的 `pico.evaluator`、`pico.metrics`、`pico.models` 和 `pico.memory` import 仍保留为兼容入口。\n"}, "67857161c73c4c48a5a221ec825316acf59fb2b2": {"t": 1785767265.4651384, "n": 3318, "h": "696446df4694dfea", "c": "# pico\n\n`pico` 是一个面向代码仓库的轻量本地 coding agent。它直接跑在终端里,先看当前工作区,再用一组受约束的工具去读文件、改文件、跑命令,并把会话状态保存在本地 `.pico/` 目录里。\n\n它更像一个能在仓库里持续工作的命令行助手,不是纯聊天窗口。你可以拿它做代码排查、测试修复、仓库分析,或者让它在当前项目里执行一次性的工程任务。\n\n## 适合做什么\n\n- 在本地仓库里排查测试失败\n- 读取当前代码结构并给出修改建议\n- 基于现有文件做小步迭代,而不是脱离仓库空想\n- 在会话中保留上下文,支持继续上一次工作\n\n## 主要特性\n\n- 包名是 `pico`\n- CLI 命令是 `pico`\n- 模块入口是 `python -m pico`\n- 会话保存在 `.pico/sessions/`\n- 每次运行的工件保存在 `.pico/runs/<run_id>/`\n- 支持四类模型后端:\n - Ollama\n - OpenAI 兼容 Responses API\n - Anthropic 兼容 Messages API\n - DeepSeek Anthropic 兼容 API\n\n## 使用截图\n\nCLI 帮助信息:\n\n\n\n启动界面:\n\n\n\nREPL 内置命令与会话路径:\n\n\n\n## 安装\n\n需要 Python 3.10+。\n\n如果你用 `uv`,直接安装依赖:\n\n```bash\nuv sync\n```\n\n如果你已经在自己的 Python 环境里工作,也可以直接装成可编辑模式:\n\n```bash\npip install -e .\n```\n\n## 快速开始\n\n在当前仓库里启动交互模式。当前推荐使用 DeepSeek:\n\n```bash\nuv run pico --provider deepseek\n```\n\n指定另一个工作目录:\n\n```bash\nuv run pico --cwd /path/to/repo\n```\n\n直接跑一次性任务:\n\n```bash\nuv run pico --provider deepseek \"inspect the test failures and propose a fix\"\n```\n\n如果当前环境已经安装过包,也可以直接这样启动:\n\n```bash\npython -m pico --provider deepseek\n```\n\n## 模型后端\n\nPico 启动时会读取项目根目录的 `.env`。本地真实 key 放在 `.env`,仓库只保留 `.env.example`。配置优先级是:\n\n```text\n显式 CLI 参数 > .env 里的 PICO_* 变量 > 旧环境变量 > 代码默认值\n```\n\n本地第一次配置:\n\n```bash\ncp .env.example .env\n```\n\n然后把要使用的 provider key 填进去。`.env` 已经被 `.gitignore` 忽略,不要提交真实 key。\n\n### Ollama\n\n```bash\nollama serve\nollama pull qwen3.5:4b\nuv run pico --provider ollama --model qwen3.5:4b\n```\n\n### OpenAI 兼容接口\n\n默认 OpenAI 兼容接口使用 right.codes 的 Codex endpoint:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://www.right.codes/codex/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n也可以改成其他 OpenAI-compatible 服务:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://your-api.example/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n```bash\nuv run pico --provider openai\n```\n\n### Anthropic 兼容接口\n\n默认 Anthropic 兼容接口使用 right.codes 的 Claude endpoint:\n\n```bash\nPICO_ANTHROPIC_API_BASE=\"https://www.right.codes/claude/v1\"\nPICO_ANTHROPIC_API_KEY=\"your-api-key\"\nPICO_ANTHROPIC_MODEL=\"claude-sonnet-4-6\"\n```\n\n```bash\nuv run pico --provider anthropic\n```\n\n如果你的服务端对多个兼容接口复用了同一套密钥,`pico` 也支持从 `PICO_ANTHROPIC_API_KEY` 回退到 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY` 或 `OPENAI_API_KEY`。\n\n### DeepSeek\n\n```bash\nPICO_DEEPSEEK_API_KEY=\"your-api-key\"\nPICO_DEEPSEEK_MODEL=\"deepseek-v4-pro\"\n```\n\n```bash\nuv run pico --provider deepseek\n```\n\n默认 DeepSeek base URL 是 `https://api.deepseek.com/anthropic`,走 DeepSeek 的 Anthropic 兼容接口。如果需要改到代理服务,可以设置 `PICO_DEEPSEEK_API_BASE` 或启动时传 `--base-url`。\n\n## 常用交互命令\n\n- `/help`:查看内置命令\n- `/memory`:查看提炼后的工作记忆\n- `/session`:查看当前会话文件路径\n- `/reset`:清空当前会话状态\n- `/exit` 或 `/quit`:退出 REPL\n\n## 安全与持久化\n\n`pico` 不会默认把所有动作都放开。像 shell 执行、文件写入这类高风险操作,会受审批模式控制:\n\n- `--approval ask`\n- `--approval auto`\n- `--approval never`\n\n每次运行结束后,都会在 `.pico/runs/<run_id>/` 下写出这些文件:\n\n- `task_state.json`\n- `trace.jsonl`\n- `report.json`\n\n这些内容默认只保存在本地,不需要跟仓库一起提交。\n\n## 开发\n\n常用本地检查:\n\n```bash\nuv run pytest tests -q\nuv run ruff check pico tests scripts\n```\n\n内部代码现在按较轻的边界拆分:`pico/evaluation/` 放 benchmark 和 metrics,`pico/providers/` 放模型 provider client,`pico/features/` 放可选运行时能力。旧的 `pico.evaluator`、`pico.metrics`、`pico.models` 和 `pico.memory` import 仍保留为兼容入口。\n"}, "f54ad9c8aa92aaaebf5d68c354487fa388698513": {"t": 1785767267.9235477, "n": 3085, "h": "2e273344f4023d89", "c": "# pico\n\n`pico` 是一个面向代码仓库的轻量本地 coding agent。它直接跑在终端里,先看当前工作区,再用一组受约束的工具去读文件、改文件、跑命令,并把会话状态保存在本地 `.pico/` 目录里。\n\n它更像一个能在仓库里持续工作的命令行助手,不是纯聊天窗口。你可以拿它做代码排查、测试修复、仓库分析,或者让它在当前项目里执行一次性的工程任务。\n\n## 适合做什么\n\n- 在本地仓库里排查测试失败\n- 读取当前代码结构并给出修改建议\n- 基于现有文件做小步迭代,而不是脱离仓库空想\n- 在会话中保留上下文,支持继续上一次工作\n\n## 主要特性\n\n- 包名是 `pico`\n- CLI 命令是 `pico`\n- 模块入口是 `python -m pico`\n- 会话保存在 `.pico/sessions/`\n- 每次运行的工件保存在 `.pico/runs/<run_id>/`\n- 支持四类模型后端:\n - Ollama\n - OpenAI 兼容 Responses API\n - Anthropic 兼容 Messages API\n - DeepSeek Anthropic 兼容 API\n\n## 使用截图\n\nCLI 帮助信息:\n\n\n\n启动界面:\n\n\n\nREPL 内置命令与会话路径:\n\n\n\n## 安装\n\n需要 Python 3.10+。\n\n如果你用 `uv`,直接安装依赖:\n\n```bash\nuv sync\n```\n\n如果你已经在自己的 Python 环境里工作,也可以直接装成可编辑模式:\n\n```bash\npip install -e .\n```\n\n## 快速开始\n\n在当前仓库里启动交互模式。当前推荐使用 DeepSeek:\n\n```bash\nuv run pico --provider deepseek\n```\n\n指定另一个工作目录:\n\n```bash\nuv run pico --cwd /path/to/repo\n```\n\n直接跑一次性任务:\n\n```bash\nuv run pico --provider deepseek \"inspect the test failures and propose a fix\"\n```\n\n如果当前环境已经安装过包,也可以直接这样启动:\n\n```bash\npython -m pico --provider deepseek\n```\n\n## 模型后端\n\nPico 启动时会读取项目根目录的 `.env`。本地真实 key 放在 `.env`,仓库只保留 `.env.example`。配置优先级是:\n\n```text\n显式 CLI 参数 > .env 里的 PICO_* 变量 > 旧环境变量 > 代码默认值\n```\n\n本地第一次配置:\n\n```bash\ncp .env.example .env\n```\n\n然后把要使用的 provider key 填进去。`.env` 已经被 `.gitignore` 忽略,不要提交真实 key。\n\n### Ollama\n\n```bash\nollama serve\nollama pull qwen3.5:4b\nuv run pico --provider ollama --model qwen3.5:4b\n```\n\n### OpenAI 兼容接口\n\n默认 OpenAI 兼容接口使用 right.codes 的 Codex endpoint:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://www.right.codes/codex/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n也可以改成其他 OpenAI-compatible 服务:\n\n```bash\nPICO_OPENAI_API_BASE=\"https://your-api.example/v1\"\nPICO_OPENAI_API_KEY=\"your-api-key\"\nPICO_OPENAI_MODEL=\"gpt-5.4\"\n```\n\n```bash\nuv run pico --provider openai\n```\n\n### Anthropic 兼容接口\n\n默认 Anthropic 兼容接口使用 right.codes 的 Claude endpoint:\n\n```bash\nPICO_ANTHROPIC_API_BASE=\"https://www.right.codes/claude/v1\"\nPICO_ANTHROPIC_API_KEY=\"your-api-key\"\nPICO_ANTHROPIC_MODEL=\"claude-sonnet-4-6\"\n```\n\n```bash\nuv run pico --provider anthropic\n```\n\n如果你的服务端对多个兼容接口复用了同一套密钥,`pico` 也支持从 `PICO_ANTHROPIC_API_KEY` 回退到 `ANTHROPIC_API_KEY`、`PICO_RIGHT_CODES_API_KEY`、`RIGHT_CODES_API_KEY`、`PICO_OPENAI_API_KEY` 或 `OPENAI_API_KEY`。\n\n### DeepSeek\n\n```bash\nPICO_DEEPSEEK_API_KEY=\"your-api-key\"\nPICO_DEEPSEEK_MODEL=\"deepseek-v4-pro\"\n```\n\n```bash\nuv run pico --provider deepseek\n```\n\n默认 DeepSeek base URL 是 `https://api.deepseek.com/anthropic`,走 DeepSeek 的 Anthropic 兼容接口。如果需要改到代理服务,可以设置 `PICO_DEEPSEEK_API_BASE` 或启动时传 `--base-url`。\n\n## 常用交互命令\n\n- `/help`:查看内置命令\n- `/memory`:查看提炼后的工作记忆\n- `/session`:查看当前会话文件路径\n- `/reset`:清空当前会话状态\n- `/exit` 或 `/quit`:退出 REPL\n\n## 安全与持久化\n\n`pico` 不会默认把所有动作都放开。像 shell 执行、文件写入这类高风险操作,会受审批模式控制:\n\n- `--approval ask`\n- `--approval auto`\n- `--approval never`\n\n每次运行结束后,都会在 `.pico/runs/<run_id>/` 下写出这些文件:\n\n- `task_state.json`\n- `trace.jsonl`\n- `report.json`\n\n这些内容默认只保存在本地,不需要跟仓库一起提交。\n\n## 开发\n\n如果装了 Ruff,可以这样检查:\n\n```bash\nuv run ruff check .\n```\n"}, "b1b4fbc7b4660a8935ce4ed5bffa2621ba2af8b9": {"t": 1785767271.2872536, "n": 2089, "h": "5ff2273bc8ed4866", "c": "# pico\n\n`pico` 是一个面向代码仓库的轻量本地 coding agent。它直接跑在终端里,先看当前工作区,再用一组受约束的工具去读文件、改文件、跑命令,并把会话状态保存在本地 `.pico/` 目录里。\n\n它更像一个能在仓库里持续工作的命令行助手,不是纯聊天窗口。你可以拿它做代码排查、测试修复、仓库分析,或者让它在当前项目里执行一次性的工程任务。\n\n## 适合做什么\n\n- 在本地仓库里排查测试失败\n- 读取当前代码结构并给出修改建议\n- 基于现有文件做小步迭代,而不是脱离仓库空想\n- 在会话中保留上下文,支持继续上一次工作\n\n## 主要特性\n\n- 包名是 `pico`\n- CLI 命令是 `pico`\n- 模块入口是 `python -m pico`\n- 会话保存在 `.pico/sessions/`\n- 每次运行的工件保存在 `.pico/runs/<run_id>/`\n- 支持三类模型后端:\n - Ollama\n - OpenAI 兼容 Responses API\n - Anthropic 兼容 Messages API\n\n## 使用截图\n\nCLI 帮助信息:\n\n\n\n启动界面:\n\n\n\nREPL 内置命令与会话路径:\n\n\n\n## 安装\n\n需要 Python 3.10+。\n\n如果你用 `uv`,直接安装依赖:\n\n```bash\nuv sync\n```\n\n如果你已经在自己的 Python 环境里工作,也可以直接装成可编辑模式:\n\n```bash\npip install -e .\n```\n\n## 快速开始\n\n在当前仓库里启动交互模式:\n\n```bash\nuv run pico\n```\n\n指定另一个工作目录:\n\n```bash\nuv run pico --cwd /path/to/repo\n```\n\n直接跑一次性任务:\n\n```bash\nuv run pico \"inspect the test failures and propose a fix\"\n```\n\n如果当前环境已经安装过包,也可以直接这样启动:\n\n```bash\npython -m pico\n```\n\n## 模型后端\n\n### Ollama\n\n```bash\nollama serve\nollama pull qwen3.5:4b\nuv run pico --provider ollama --model qwen3.5:4b\n```\n\n### OpenAI 兼容接口\n\n```bash\nexport OPENAI_API_BASE=\"https://your-api.example/v1\"\nexport OPENAI_API_KEY=\"your-api-key\"\nexport OPENAI_MODEL=\"gpt-5.4\"\nuv run pico --provider openai\n```\n\n### Anthropic 兼容接口\n\n```bash\nexport ANTHROPIC_API_BASE=\"https://www.right.codes/claude/v1\"\nexport ANTHROPIC_API_KEY=\"your-api-key\"\nexport ANTHROPIC_MODEL=\"claude-sonnet-4-6\"\nuv run pico --provider anthropic\n```\n\n如果你的服务端对多个兼容接口复用了同一套密钥,`pico` 也支持从 `ANTHROPIC_API_KEY` 回退到 `RIGHT_CODES_API_KEY` 或 `OPENAI_API_KEY`。\n\n## 常用交互命令\n\n- `/help`:查看内置命令\n- `/memory`:查看提炼后的工作记忆\n- `/session`:查看当前会话文件路径\n- `/reset`:清空当前会话状态\n- `/exit` 或 `/quit`:退出 REPL\n\n## 安全与持久化\n\n`pico` 不会默认把所有动作都放开。像 shell 执行、文件写入这类高风险操作,会受审批模式控制:\n\n- `--approval ask`\n- `--approval auto`\n- `--approval never`\n\n每次运行结束后,都会在 `.pico/runs/<run_id>/` 下写出这些文件:\n\n- `task_state.json`\n- `trace.jsonl`\n- `report.json`\n\n这些内容默认只保存在本地,不需要跟仓库一起提交。\n\n## 开发\n\n如果装了 Ruff,可以这样检查:\n\n```bash\nuv run ruff check .\n```\n"}}, "tests/test_safety_invariants.py": {"74022538904a2ca69d28689d30d5e5284e09fb15": {"t": 1786068249.3157532, "n": 9268, "h": "03296768cb31e88f", "c": "import os\nimport shlex\nimport sys\nfrom unittest.mock import patch\n\nfrom pico import FakeModelClient, Pico, SessionStore, WorkspaceContext\nfrom pico import cli as pico_cli\nfrom pico.task_state import TaskState\n\n\ndef build_workspace(tmp_path):\n (tmp_path / \"README.md\").write_text(\"demo\\n\", encoding=\"utf-8\")\n return WorkspaceContext.build(tmp_path)\n\n\ndef build_agent(tmp_path, outputs, **kwargs):\n workspace = build_workspace(tmp_path)\n store = SessionStore(tmp_path / \".pico\" / \"sessions\")\n approval_policy = kwargs.pop(\"approval_policy\", \"auto\")\n return Pico(\n model_client=FakeModelClient(outputs),\n workspace=workspace,\n session_store=store,\n approval_policy=approval_policy,\n **kwargs,\n )\n\n\ndef test_workspace_escape_is_rejected(tmp_path):\n (tmp_path / \"outside.txt\").write_text(\"outside\\n\", encoding=\"utf-8\")\n agent = build_agent(tmp_path, [])\n\n result = agent.run_tool(\"read_file\", {\"path\": \"../outside.txt\"})\n\n assert \"path escapes workspace\" in result\n\n\ndef test_symlink_path_traversal_is_rejected(tmp_path):\n outside = tmp_path.parent / f\"{tmp_path.name}-outside.txt\"\n outside.write_text(\"outside\\n\", encoding=\"utf-8\")\n (tmp_path / \"linked.txt\").symlink_to(outside)\n agent = build_agent(tmp_path, [])\n\n result = agent.run_tool(\"read_file\", {\"path\": \"linked.txt\"})\n\n assert \"path escapes workspace\" in result\n\n\ndef test_risky_tool_deny_behavior(tmp_path):\n agent = build_agent(tmp_path, [], approval_policy=\"never\")\n\n result = agent.run_tool(\"run_shell\", {\"command\": \"echo hi\", \"timeout\": 20})\n\n assert result == \"error: approval denied for run_shell\"\n\n\ndef test_cli_build_agent_wires_secret_env_names_from_parser(tmp_path):\n class DummyModelClient:\n def __init__(self, *args, **kwargs):\n self.args = args\n self.kwargs = kwargs\n\n def complete(self, prompt, max_new_tokens):\n raise AssertionError(\"model should not be invoked\")\n\n (tmp_path / \"README.md\").write_text(\"demo\\n\", encoding=\"utf-8\")\n with patch.dict(os.environ, {\"GITHUB_PAT\": \"ghp-1\", \"GH_PAT\": \"ghp-2\"}, clear=True), patch(\n \"pico.cli.OllamaModelClient\",\n DummyModelClient,\n ):\n args = pico_cli.build_arg_parser().parse_args(\n [\n \"--cwd\",\n str(tmp_path),\n \"--approval\",\n \"auto\",\n \"--secret-env-name\",\n \"GITHUB_PAT\",\n \"--secret-env-name\",\n \"GH_PAT\",\n ]\n )\n agent = pico_cli.build_agent(args)\n assert set(agent.secret_env_summary()[\"secret_env_names\"]) == {\"GITHUB_PAT\", \"GH_PAT\"}\n\n\ndef test_cli_build_agent_uses_default_configured_secret_names(tmp_path):\n class DummyModelClient:\n def __init__(self, *args, **kwargs):\n self.args = args\n self.kwargs = kwargs\n\n def complete(self, prompt, max_new_tokens):\n raise AssertionError(\"model should not be invoked\")\n\n (tmp_path / \"README.md\").write_text(\"demo\\n\", encoding=\"utf-8\")\n with patch.dict(os.environ, {\"GH_PAT\": \"ghp-default-1\"}, clear=True), patch(\n \"pico.cli.OllamaModelClient\",\n DummyModelClient,\n ):\n args = pico_cli.build_arg_parser().parse_args([\"--cwd\", str(tmp_path), \"--approval\", \"auto\"])\n agent = pico_cli.build_agent(args)\n assert agent.secret_env_summary()[\"secret_env_names\"] == [\"GH_PAT\"]\n\n\ndef test_cli_build_agent_loads_project_env_secrets_before_redaction_setup(tmp_path):\n class DummyModelClient:\n def __init__(self, *args, **kwargs):\n self.args = args\n self.kwargs = kwargs\n\n def complete(self, prompt, max_new_tokens):\n raise AssertionError(\"model should not be invoked\")\n\n (tmp_path / \"README.md\").write_text(\"demo\\n\", encoding=\"utf-8\")\n (tmp_path / \".env\").write_text(\"PICO_DEEPSEEK_API_KEY=sk-project-secret\\n\", encoding=\"utf-8\")\n with patch.dict(os.environ, {}, clear=True), patch(\"pico.cli.AnthropicCompatibleModelClient\", DummyModelClient):\n args = pico_cli.build_arg_parser().parse_args([\"--cwd\", str(tmp_path), \"--provider\", \"deepseek\"])\n agent = pico_cli.build_agent(args)\n assert agent.secret_env_summary()[\"secret_env_names\"] == [\"PICO_DEEPSEEK_API_KEY\"]\n\n\ndef test_cli_build_agent_reads_secret_names_from_environment_config(tmp_path):\n class DummyModelClient:\n def __init__(self, *args, **kwargs):\n self.args = args\n self.kwargs = kwargs\n\n def complete(self, prompt, max_new_tokens):\n raise AssertionError(\"model should not be invoked\")\n\n (tmp_path / \"README.md\").write_text(\"demo\\n\", encoding=\"utf-8\")\n with patch.dict(\n os.environ,\n {\n \"PICO_CUSTOM_SECRET\": \"custom-secret-value\",\n \"PICO_SECRET_ENV_NAMES\": \"PICO_CUSTOM_SECRET\",\n },\n clear=True,\n ), patch(\"pico.cli.OllamaModelClient\", DummyModelClient):\n args = pico_cli.build_arg_parser().parse_args([\"--cwd\", str(tmp_path), \"--approval\", \"auto\"])\n agent = pico_cli.build_agent(args)\n assert agent.secret_env_summary()[\"secret_env_names\"] == [\"PICO_CUSTOM_SECRET\"]\n\n\ndef test_run_shell_uses_allowlisted_environment_only(tmp_path):\n secret = \"shh-allowlist-secret\"\n agent = build_agent(tmp_path, [], approval_policy=\"auto\")\n script = 'import os; print(os.getenv(\"PICO_ALLOWLIST_SECRET\", \"missing\"))'\n command = f\"{shlex.quote(sys.executable)} -c {shlex.quote(script)}\"\n\n with patch.dict(os.environ, {\"PICO_ALLOWLIST_SECRET\": secret}, clear=False):\n result = agent.run_tool(\"run_shell\", {\"command\": command, \"timeout\": 20})\n\n assert secret not in result\n assert \"missing\" in result\n\n\ndef test_bound_tool_methods_delegate_into_tools_module(tmp_path):\n agent = build_agent(tmp_path, [], approval_policy=\"auto\")\n\n with patch(\"pico.tools.subprocess.run\") as fake_run:\n fake_run.return_value = type(\n \"Result\",\n (),\n {\"returncode\": 0, \"stdout\": \"toolkit-shell\\n\", \"stderr\": \"\"},\n )()\n shell_result = agent.tool_run_shell({\"command\": \"echo bypass\", \"timeout\": 20})\n\n assert \"toolkit-shell\" in shell_result\n fake_run.assert_called_once()\n assert agent.tool_run_shell.__func__.__module__ == \"pico.runtime\"\n\n with patch(\"pico.tools.tool_delegate\", return_value=\"toolkit-delegate\") as fake_delegate:\n delegate_result = agent.tool_delegate({\"task\": \"inspect README.md\", \"max_steps\": 2})\n\n assert delegate_result == \"toolkit-delegate\"\n fake_delegate.assert_called_once()\n\n\ndef test_delegate_depth_limit_is_enforced(tmp_path):\n agent = build_agent(tmp_path, [], depth=1, max_depth=1)\n\n try:\n agent.validate_tool(\"delegate\", {\"task\": \"inspect README.md\", \"max_steps\": 2})\n except ValueError as exc:\n assert \"delegate depth exceeded\" in str(exc)\n else:\n raise AssertionError(\"delegate depth validation did not fail\")\n\n\ndef test_delegate_child_is_read_only(tmp_path):\n target = tmp_path / \"child-was-not-allowed.txt\"\n agent = build_agent(\n tmp_path,\n [\n '<tool>{\"name\":\"delegate\",\"args\":{\"task\":\"write a file\",\"max_steps\":2}}</tool>',\n '<tool>{\"name\":\"write_file\",\"args\":{\"path\":\"child-was-not-allowed.txt\",\"content\":\"nope\"}}</tool>',\n \"<final>child done</final>\",\n \"<final>parent done</final>\",\n ],\n )\n\n result = agent.ask(\"Delegate the work\")\n\n assert result == \"parent done\"\n assert not target.exists()\n tool_events = [item for item in agent.session[\"history\"] if item[\"role\"] == \"tool\"]\n assert tool_events[0][\"name\"] == \"delegate\"\n assert \"delegate_result\" in tool_events[0][\"content\"]\n\n\ndef test_configured_secret_env_names_are_redacted_in_trace_and_report(tmp_path):\n github_pat = \"ghp_configured_secret_123\"\n gh_pat = \"ghp_configured_secret_456\"\n with patch.dict(os.environ, {\"GITHUB_PAT\": github_pat, \"GH_PAT\": gh_pat}, clear=True):\n agent = build_agent(\n tmp_path,\n [],\n secret_env_names=(\"GITHUB_PAT\", \"GH_PAT\"),\n )\n state = TaskState.create(run_id=\"run_001\", task_id=\"task_001\", user_request=\"Mask configured secrets\")\n agent.run_store.start_run(state)\n\n assert set(agent.secret_env_summary()[\"secret_env_names\"]) == {\"GITHUB_PAT\", \"GH_PAT\"}\n\n payload = {\n \"GITHUB_PAT\": github_pat,\n \"GH_PAT\": gh_pat,\n \"nested\": {\"GITHUB_PAT\": github_pat, \"GH_PAT\": gh_pat},\n \"list\": [github_pat, gh_pat],\n }\n agent.emit_trace(state, \"tool_executed\", payload)\n agent.run_store.write_report(\n state,\n agent.redact_artifact({\"task_state\": state.to_dict(), \"payload\": payload}),\n )\n\n run_dir = agent.run_store.run_dir(state.run_id)\n trace_text = (run_dir / \"trace.jsonl\").read_text(encoding=\"utf-8\")\n report_text = (run_dir / \"report.json\").read_text(encoding=\"utf-8\")\n\n assert github_pat not in trace_text\n assert gh_pat not in trace_text\n assert github_pat not in report_text\n assert gh_pat not in report_text\n assert trace_text.count(\"<redacted>\") >= 4\n assert report_text.count(\"<redacted>\") >= 4\n"}}}} |