Skip to content

Commit 623d60c

Browse files
committed
refactor: 迁移本地配置至env/secrets.json并重构用户画像同步
1 parent 454aa9d commit 623d60c

17 files changed

Lines changed: 220 additions & 100 deletions

‎.gitignore‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
.DS_Store
22

3-
# skills-engineering: local machine sync config (see scripts/config.local.sh.example)
4-
skills-engineering/scripts/config.local.sh
5-
63
# env/: only secrets.json is gitignored.
74
# env/mcp/*.json and env/platforms/*.json are committed (use ${VAR} references, no real secrets).
85
# User only needs to create env/secrets.json from env/secrets.json.example.

‎USER.md.example‎

Lines changed: 0 additions & 32 deletions
This file was deleted.

‎env/README.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ bash sync/scripts/optional_mcps.sh disable puppeteer
185185
"gemini": "/custom/.gemini",
186186
"codebuddy": "/custom/.codebuddy",
187187
"cursor": "/custom/.cursor",
188+
"cursor_project_roots": [
189+
"/path/to/appA",
190+
"/path/to/appB"
191+
],
188192
"cline": "/custom/.cline",
189193
"continue": "/custom/.continue",
190194
"qwen": "/custom/.qwen",
@@ -195,6 +199,7 @@ bash sync/scripts/optional_mcps.sh disable puppeteer
195199

196200
- 键名与平台一致;留空字符串 `""` 或删除该键即回退默认路径。
197201
- 设置后,该平台的所有派生路径(配置、settings、skills、MCP 文件等)都会基于覆盖值解析。
202+
- `cursor_project_roots` 是额外的 Cursor 项目根列表,用于同步项目内 `.cursor/rules/*.mdc`;也可用 `CURSOR_PROJECT_ROOTS="/path/a:/path/b"` 临时覆盖。
198203
- Codex 仍优先使用标准环境变量 `CODEX_HOME` / `CODEX_CONFIG`,其次才是此处覆盖。
199204
- `paths` 不是密钥,不会参与 `${...}` 占位符注入,仅用于路径解析。
200205

‎env/secrets.json.example‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747
"gemini": "",
4848
"codebuddy": "",
4949
"cursor": "",
50+
"cursor_project_roots": [
51+
"/Users/you/path/to/projA",
52+
"/Users/you/path/to/projB"
53+
],
5054
"cline": "",
5155
"continue": "",
5256
"qwen": "",

‎env/user-profile.json.example‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"_enabled_options": "enabled 必须是字符串 \"auto\" | \"on\" | \"off\"(不能写布尔值 true/false,否则会被判为无效配置并报错退出)。auto:画像文件存在才同步,不存在则跳过;on:强制同步,画像不存在或为空则报错;off:跳过同步。",
3+
"enabled": "auto",
4+
"source": "env/user-profile.md"
5+
}

‎env/user-profile.md.example‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# user-profile.md — 跨会话用户画像模板
2+
3+
> 复制为 `env/user-profile.md`(同目录,已被 .gitignore 排除,不提交),填写你的真实信息:
4+
>
5+
> ```bash
6+
> cp env/user-profile.md.example env/user-profile.md
7+
> ```
8+
>
9+
> 可选:复制 `env/user-profile.json.example` 为 `env/user-profile.json`,调整启用状态或画像路径:
10+
>
11+
> ```bash
12+
> cp env/user-profile.json.example env/user-profile.json
13+
> ```
14+
>
15+
> `skills-engineering/scripts/sync-user-profile.sh` 会把它同步到 `~/.ai-coding-kit/USER.md`
16+
> 并注入各端 Agent preamble 的 `user-profile` 托管块,使各 AI 工具共享同一份长期画像。
17+
>
18+
> **分工提醒**:若你已经在用各端 Agent preamble / skills / AGENTS.md 约定通用行为规则
19+
> (如“不确定时怎么说”“是否主动建议”“代码修改后如何验证”),这里不用重复写。
20+
> 本文件只写规则管不到、但会长期影响协作质量的个人上下文:你是谁、熟悉什么、正在长期做什么、
21+
> 哪些边界对你特别重要。优先写真实场景例子,少写抽象标签。
22+
23+
## 身份与背景
24+
- 姓名 / 称呼:
25+
- 主要角色:______(如 iOS 工程师 / 全栈 / 技术负责人 / 学生)
26+
- 常用语言:中文 / English(回答默认语言:______)
27+
- 经验分布(决定 AI 是否需要解释基础概念):
28+
- 熟:______(如 iOS/Swift 十年,不需要解释语言基础)
29+
- 生:______(如刚接触前端,术语请配一句白话解释)
30+
- 我常承担的职责:______(如写代码 / 做架构判断 / code review / 产品拆解 / 技术管理)
31+
32+
## 长期工作脉络
33+
- 主要在做的方向 / 技术栈:
34+
- 常见项目类型:______(如 iOS App / AI Coding 工具 / 后端服务 / 内部平台)
35+
- 默认优先级排序:______(如正确性 > 可维护性 > 兼容性 > 迭代速度)
36+
- 长期背景信息:______(只写跨项目稳定、AI 经常需要知道的上下文;不要写一次性任务流水账)
37+
38+
## 沟通偏好
39+
尽量写“场景 + 期望输出”,不要只写“简洁 / 详细”这类标签。
40+
41+
- 例:______(如“review 类回复先列问题和风险,摘要放后面”)
42+
- 例:______(如“解释技术选型时,先说结论,再说理由,不要先铺背景”)
43+
- 例:______(如“我熟悉的技术可以少解释基础概念;陌生领域请先补一两句上下文”)
44+
45+
## 个人化边界
46+
不要重复项目规则或通用安全规则;这里只写和你个人长期相关的边界。
47+
48+
- 敏感项目 / 不可外传的信息:
49+
- 个人额外在意的红线:
50+
- AI 容易误判你的地方:______(如“我问方案时通常希望被挑战,而不是只要赞同”)
51+
52+
## 设备与环境
53+
- OS:macOS / Linux / Windows
54+
- 常用编辑器 / IDE:
55+
- 已安装的 AI 工具:Codex / Claude Code / Cursor / Gemini / Cline / 其他
56+
- 常用终端 / Shell:
57+
58+
<!--
59+
维护建议:
60+
- 只写长期稳定的信息;项目专属规则放项目 AGENTS.md / README。
61+
- 每条偏好最好能影响 AI 的默认判断,否则可以不写。
62+
- 本文件由你自己维护,不提交真实内容。
63+
-->

‎skills-engineering/README.md‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,10 @@
6767
│ ├── bootstrap.sh
6868
│ ├── sync-skills.sh
6969
│ ├── sync-agent-preamble.sh
70-
│ ├── sync-user-profile.sh # 跨会话用户画像(USER.md → ~/.ai-coding-kit/USER.md → preamble 托管块)
70+
│ ├── sync-user-profile.sh # 跨会话用户画像(env/user-profile.md → ~/.ai-coding-kit/USER.md → preamble 托管块)
7171
│ ├── sync-memory.sh # 跨会话事件级记忆(MEMORY.md + remember/recall + preamble 托管块)
7272
│ ├── verify-sync.sh
7373
│ ├── list-skills.sh
74-
│ ├── config.local.sh.example
7574
│ └── templates/
7675
├── docs/ # 各 skill 使用文档(供人类阅读)
7776
├── .agents/ # Agent 调用规范与文档写作规范
@@ -84,7 +83,7 @@
8483
- `ios-engineer/references/`:按主题拆分的技能规则与参考材料,例如认知对手模式、并发、布局、网络、性能、审查、迁移、测试、可观测性和自进化治理。
8584
- `ios-engineer/scripts/`:技能演进、校验、提案、验证、晋升、回滚、usage ledger 写入与汇总脚本。
8685
- `ios-engineer/evolution/`:技能演进数据,包括 `proposals/`、`validations/`、`approvals/`、`history/`、`scenarios/`、`usage/`。
87-
- `scripts/`:仓库级脚本,负责同步技能、同步 Agent preamble 与同步结果校验;本地机器专属配置放在 `scripts/config.local.sh`(模板为 `scripts/config.local.sh.example`),路径由仓库根 `.gitignore` 排除,会被 sync 脚本自动 source。
86+
- `scripts/`:仓库级脚本,负责同步技能、同步 Agent preamble 与同步结果校验;本机专属路径配置统一放在仓库根 `env/secrets.json`。
8887
- `docs/`:各 skill 的独立使用文档,供人类阅读,不参与 Agent 运行时加载。
8988
- `.agents/`:`invocation.md`(多 skill 并行加载规范)、`composition.md`(多技能同时命中时的块发射顺序与冲突裁决)和 `writing-docs.md`(文档写作规范)。
9089
- `.claude-plugin/plugin.json`:Claude Code 插件清单,支持一键安装为 Claude 插件。
@@ -214,9 +213,9 @@ SYNC_CLAUDE=0 SYNC_CODEX=0 SYNC_CURSOR=0 SYNC_XCODE_CODEX=0 SYNC_XCODE_CLAUDE=1
214213
CURSOR_PROJECT_ROOTS="/path/to/appA:/path/to/appB" ./scripts/sync-agent-preamble.sh
215214
```
216215

217-
也可以把 `CURSOR_PROJECT_ROOTS` 写进 `scripts/config.local.sh`(从 `scripts/config.local.sh.example` 复制得到;该文件已由仓库根 `.gitignore` 按路径 `skills-engineering/scripts/config.local.sh` 排除),脚本启动时会自动 source,CLI / shell 变量仍然优先。
216+
也可以把外部 Cursor 项目根写进 `env/secrets.json` 的 `paths.cursor_project_roots`。命令行传入的 `CURSOR_PROJECT_ROOTS` 仍然优先,适合一次性覆盖。
218217

219-
Claude / Codex 两端同样遵循 `SYNC_CLAUDE` / `SYNC_CODEX` 门控语义(`1 / 0 / 留空自动探测`);Cursor 侧由 `CURSOR_PROJECT_ROOTS` 是否设置来决定,不复用 `SYNC_CURSOR`。
218+
Claude / Codex 两端同样遵循 `SYNC_CLAUDE` / `SYNC_CODEX` 门控语义(`1 / 0 / 留空自动探测`);Cursor 项目规则由 `env/secrets.json` 的 `paths.cursor_project_roots` 或临时 `CURSOR_PROJECT_ROOTS` 决定,不复用 `SYNC_CURSOR`。
220219
Xcode Codex / Claude 侧分别遵循 `SYNC_XCODE_CODEX` / `SYNC_XCODE_CLAUDE` 门控语义(`1 / 0 / 留空自动探测`),默认写入 `codex/AGENTS.md` 与 `ClaudeAgentConfig/CLAUDE.md`。
221220

222221
脚本只重写 `<!-- managed-block:agent-preamble:begin ... :end -->` 托管块(并兼容迁移旧的 `ios-engineer` 托管块标记),保留文件中的其他内容。
@@ -253,13 +252,13 @@ curl -fsSL https://raw.githubusercontent.com/i-stack/ai-coding-kit/main/skills-e
253252
- `SKIP_PREAMBLE=true`:跳过 `sync-agent-preamble.sh`
254253
- `SKIP_USER_PROFILE=true`:跳过 `sync-user-profile.sh`(跨会话用户画像)
255254
- `SKIP_MEMORY=true`:跳过 `sync-memory.sh`(跨会话事件记忆)
256-
- `CURSOR_PROJECT_ROOTS`:透传给 `sync-agent-preamble.sh`
255+
- `CURSOR_PROJECT_ROOTS`:临时覆盖 `env/secrets.json` 的 `paths.cursor_project_roots`,透传给 `sync-agent-preamble.sh`
257256

258257
### 5. 跨会话记忆(用户画像 + 事件记忆)
259258

260259
对标 Hermes Agent 的持久记忆系统,提供两层互补的长期记忆,均跨会话、跨端共享:
261260

262-
**L0 — 用户画像(`sync-user-profile.sh`)**:用户从仓库根 `USER.md.example` 复制出 `USER.md`(已 gitignore)手动维护稳定偏好 / 角色 / 约束;脚本把画像同步到 `~/.ai-coding-kit/USER.md`,并在各端 preamble 注入独立的 `user-profile` 托管块(与 agent-preamble 块互不干扰)。
261+
**L0 — 用户画像(`sync-user-profile.sh`)**:用户从 `env/user-profile.md.example` 复制出 `env/user-profile.md`(已 gitignore)手动维护稳定偏好 / 角色 / 约束;`env/user-profile.json` 提供 `auto/on/off` 开关与画像路径配置。脚本把画像同步到 `~/.ai-coding-kit/USER.md`,并在各端 preamble 注入独立的 `user-profile` 托管块(与 agent-preamble 块互不干扰)。
263262

264263
**L1 — 事件级记忆(`sync-memory.sh`)**:交互中累积的纠正、项目约定与决策理由,落在本机 `~/.ai-coding-kit/MEMORY.md`(仓库外,无需 gitignore)。脚本向各端 preamble 注入独立的 `user-memory` 托管块,并把自身复制到 `~/.ai-coding-kit/sync-memory.sh` 作为 Agent 的稳定调用入口:
265264

@@ -494,7 +493,7 @@ git push --no-verify # 跳过整个 pre-push(含 sync/scripts/
494493
- 提交前运行 `./scripts/sync-skills.sh --dry-run` 和 `bash ios-engineer/scripts/validate_skill_evolution.sh`。
495494
- 修改托管 preamble 时只改 `scripts/templates/agent-preamble.md.tmpl`,再运行 `./scripts/sync-agent-preamble.sh --dry-run` 检查输出。
496495
- 推送前(或 `SKILL_BYPASS=1` 推送后)手动跑 `./scripts/verify-sync.sh` 确认各已启用缓存与 preamble 状态一致,避免 Agent 侧加载漂移版本。
497-
- 本机专属配置(如 `CURSOR_PROJECT_ROOTS`)写进 `scripts/config.local.sh`(由 `scripts/config.local.sh.example` 复制);该路径在仓库根 `.gitignore` 中已排除,切勿提交进仓库。
496+
- 本机专属配置(如外部 Cursor 项目根)写进仓库根 `env/secrets.json`;该文件已由仓库根 `.gitignore` 排除,切勿提交进仓库。
498497

499498
## 变更记录
500499

‎skills-engineering/scripts/bootstrap.sh‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
# the script prompts interactively (Enter = default).
2727
# Default: ~/Desktop/github/ai-coding-kit
2828
# REF Branch/tag/commit to check out after clone. Default: main
29-
# CURSOR_PROJECT_ROOTS Passthrough to sync-agent-preamble.sh (optional)
29+
# CURSOR_PROJECT_ROOTS One-shot override for env/secrets.json paths.cursor_project_roots
3030
# SKIP_PREAMBLE=true Skip sync-agent-preamble.sh
3131
# SKIP_SKILLS=true Skip sync-skills.sh
3232
# SKIP_CLAUDE_HOOKS=true Skip sync-claude-hooks.sh
@@ -107,7 +107,9 @@ fi
107107
if [[ "${SKIP_USER_PROFILE:-false}" != "true" ]]; then
108108
echo "---"
109109
echo "Running sync-user-profile.sh"
110-
"${SCRIPTS_DIR}/sync-user-profile.sh"
110+
if ! "${SCRIPTS_DIR}/sync-user-profile.sh"; then
111+
echo " sync-user-profile.sh FAILED (optional; continuing)" >&2
112+
fi
111113
fi
112114

113115
if [[ "${SKIP_MEMORY:-false}" != "true" ]]; then

‎skills-engineering/scripts/config.local.sh.example‎

Lines changed: 0 additions & 14 deletions
This file was deleted.

‎skills-engineering/scripts/sync-agent-preamble.sh‎

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@ set -euo pipefail
44

55
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
66

7-
LOCAL_CONFIG="${SCRIPT_DIR}/config.local.sh"
8-
if [[ -f "${LOCAL_CONFIG}" ]]; then
9-
# shellcheck disable=SC1090
10-
source "${LOCAL_CONFIG}"
11-
fi
12-
137
# Resolve a platform's install root via the SAME source as the Python sync engine
148
# (sync/core/paths.py -> platform_install_root). Honors the top-level `paths`
159
# override in env/secrets.json AND platform-specific defaults (e.g. CODEX_HOME for
@@ -41,7 +35,6 @@ CODEX_TARGET="${CODEX_TARGET:-${HOME}/.codex/AGENTS.md}"
4135
GEMINI_TARGET="${GEMINI_TARGET:-${HOME}/.gemini/GEMINI.md}"
4236
XCODE_CODEX_TARGET="${XCODE_CODEX_TARGET:-${HOME}/Library/Developer/Xcode/CodingAssistant/codex/AGENTS.md}"
4337
XCODE_CLAUDE_TARGET="${XCODE_CLAUDE_TARGET:-${HOME}/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/CLAUDE.md}"
44-
CURSOR_PROJECT_ROOTS="${CURSOR_PROJECT_ROOTS:-}"
4538
# Recall-only preamble targets (cline / qwen) and full preamble
4639
# targets (claude / codex / gemini / xcode / codebuddy) are now discovered from each
4740
# platform's `preamble` declaration in env/platforms/<platform>.json — see the
@@ -69,6 +62,36 @@ REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
6962
RECALL_CLI_PATH="${REPO_ROOT}/skills-engineering/plan-reviews/dist/cli.js"
7063
SE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
7164

65+
resolve_cursor_project_roots() {
66+
if [[ -n "${CURSOR_PROJECT_ROOTS:-}" ]]; then
67+
printf '%s\n' "${CURSOR_PROJECT_ROOTS}"
68+
return
69+
fi
70+
python3 - "${REPO_ROOT}/env/secrets.json" <<'PY'
71+
import json
72+
import sys
73+
from pathlib import Path
74+
75+
path = Path(sys.argv[1])
76+
try:
77+
data = json.loads(path.read_text(encoding="utf-8"))
78+
except (OSError, json.JSONDecodeError):
79+
sys.exit(0)
80+
81+
paths = data.get("paths")
82+
if not isinstance(paths, dict):
83+
sys.exit(0)
84+
85+
roots = paths.get("cursor_project_roots")
86+
if isinstance(roots, str):
87+
print(roots)
88+
elif isinstance(roots, list):
89+
print(":".join(str(root) for root in roots if isinstance(root, str) and root.strip()))
90+
PY
91+
}
92+
93+
CURSOR_PROJECT_ROOTS="$(resolve_cursor_project_roots)"
94+
7295
DRY_RUN=false
7396

7497
usage() {
@@ -89,7 +112,7 @@ Recall-only targets (historical-recall managed block, no ios-engineer audit):
89112
90113
Cursor project rules (from sync-manifest skill:* lines):
91114
<repo>/.cursor/rules/<skill>.mdc
92-
<CURSOR_PROJECT_ROOTS>/.cursor/rules/<skill>.mdc
115+
<env/secrets.json paths.cursor_project_roots>/.cursor/rules/<skill>.mdc
93116
94117
Skill full text is synced by sync-skills.sh to ~/.*/skills/<skill>/ — run
95118
sync-skill-full.sh or sync-skills.sh before this script.
@@ -546,5 +569,5 @@ if [[ -n "${CURSOR_PROJECT_ROOTS}" ]]; then
546569
sync_manifest_skill_cursor_rules "${_root}"
547570
done
548571
else
549-
echo "CURSOR_PROJECT_ROOTS not set; skipping Cursor ios-engineer.mdc on external projects."
572+
echo "paths.cursor_project_roots not set in env/secrets.json; skipping Cursor ios-engineer.mdc on external projects."
550573
fi

0 commit comments

Comments
 (0)