@sakanano-moe/agenthelm 6.8.0 → 6.11.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/package.json +1 -1
  2. package/runtime/index.json +6 -6
  3. package/runtime/plugins/agent-pack/.codex-plugin/plugin.json +1 -1
  4. package/runtime/plugins/agent-pack/hooks/hooks.json +32 -0
  5. package/runtime/plugins/agent-pack/plugin.json +1 -1
  6. package/runtime/plugins/agent-pack/references/local-only.md +126 -0
  7. package/runtime/plugins/agent-pack/references/nudge.en.md +58 -0
  8. package/runtime/plugins/agent-pack/references/nudge.md +58 -0
  9. package/runtime/plugins/agent-pack/runtime/agent_pack_nudge.py +573 -0
  10. package/runtime/plugins/agent-pack/runtime/agenthelm.py +228 -147
  11. package/runtime/plugins/agent-pack/runtime/agenthelm_runtime.py +64 -59
  12. package/runtime/plugins/agent-pack/runtime/i18n_agent_pack.py +78 -0
  13. package/runtime/plugins/agent-pack/runtime/local_only.py +1130 -0
  14. package/runtime/plugins/agent-pack/runtime/locale/en.json +385 -0
  15. package/runtime/plugins/agent-pack/runtime/mcp_server.py +25 -0
  16. package/runtime/plugins/agent-pack/runtime/nudge_text.py +107 -0
  17. package/runtime/plugins/agent-pack/skills/agent-pack/SKILL.md +9 -1
  18. package/runtime/plugins/agents-init/.codex-plugin/plugin.json +1 -1
  19. package/runtime/plugins/agents-init/content.json +4 -4
  20. package/runtime/plugins/agents-init/plugin.json +1 -1
  21. package/runtime/plugins/agents-init/skills/agents-init/AGENT.template.md +47 -0
  22. package/runtime/plugins/agents-init/skills/agents-init/SKILL.md +26 -1
  23. package/runtime/plugins/agents-init/skills/agents-init/project.schema.json +399 -80
  24. package/runtime/plugins/agents-init/skills/agents-init/scripts/adopt.py +596 -0
  25. package/runtime/plugins/agents-init/skills/agents-init/scripts/i18n_init.py +78 -0
  26. package/runtime/plugins/agents-init/skills/agents-init/scripts/init_project.py +210 -76
  27. package/runtime/plugins/agents-init/skills/agents-init/scripts/locale/en.json +210 -0
  28. package/runtime/plugins/agents-init/skills/agents-init/scripts/regions.py +99 -0
  29. package/runtime/plugins/agents-init/skills/agents-init/scripts/scaffold.py +210 -62
  30. package/runtime/plugins/agents-init/skills/agents-init/scripts/test_adopt.py +551 -0
  31. package/runtime/plugins/agents-init/skills/agents-init/scripts/test_init_project.py +46 -2
  32. package/runtime/plugins/agents-init/skills/agents-init/scripts/test_scaffold.py +4 -0
  33. package/runtime/plugins/agents-init/skills/agents-init/skeleton.json +2 -0
  34. package/runtime/plugins/agents-init/skills/agents-init/skill.json +1 -1
  35. package/runtime/plugins/opinion-manager/.codex-plugin/plugin.json +1 -1
  36. package/runtime/plugins/opinion-manager/plugin.json +1 -1
  37. package/runtime/plugins/opinion-manager/references/inbox.en.md +48 -0
  38. package/runtime/plugins/opinion-manager/references/inbox.md +48 -0
  39. package/runtime/plugins/opinion-manager/runtime/context.py +19 -18
  40. package/runtime/plugins/opinion-manager/runtime/i18n_opinion.py +78 -0
  41. package/runtime/plugins/opinion-manager/runtime/inbox.py +397 -0
  42. package/runtime/plugins/opinion-manager/runtime/inbox_text.py +101 -0
  43. package/runtime/plugins/opinion-manager/runtime/lifecycle.py +45 -44
  44. package/runtime/plugins/opinion-manager/runtime/locale/en.json +184 -0
  45. package/runtime/plugins/opinion-manager/runtime/opinion_manager.py +55 -50
  46. package/runtime/plugins/opinion-manager/runtime/versioned.py +84 -83
  47. package/runtime/plugins/opinion-manager/skills/opinion-manager/SKILL.md +15 -2
  48. package/runtime/plugins/project-orchestrator/.codex-plugin/plugin.json +1 -1
  49. package/runtime/plugins/project-orchestrator/content.json +30 -3
  50. package/runtime/plugins/project-orchestrator/plugin.json +1 -1
  51. package/runtime/plugins/project-orchestrator/references/case-workspaces.md +9 -1
  52. package/runtime/plugins/project-orchestrator/references/case.schema.json +1 -0
  53. package/runtime/plugins/project-orchestrator/references/sop-interview.md +83 -0
  54. package/runtime/plugins/project-orchestrator/references/sop.md +156 -0
  55. package/runtime/plugins/project-orchestrator/runtime/assets.py +52 -57
  56. package/runtime/plugins/project-orchestrator/runtime/case.py +139 -80
  57. package/runtime/plugins/project-orchestrator/runtime/case_structure.py +71 -0
  58. package/runtime/plugins/project-orchestrator/runtime/case_workspace.py +47 -46
  59. package/runtime/plugins/project-orchestrator/runtime/i18n_orchestrator.py +78 -0
  60. package/runtime/plugins/project-orchestrator/runtime/locale/en.json +1409 -0
  61. package/runtime/plugins/project-orchestrator/runtime/memory.py +44 -43
  62. package/runtime/plugins/project-orchestrator/runtime/private_paths.py +119 -0
  63. package/runtime/plugins/project-orchestrator/runtime/project_base.py +37 -19
  64. package/runtime/plugins/project-orchestrator/runtime/project_cli.py +222 -189
  65. package/runtime/plugins/project-orchestrator/runtime/project_demo.py +130 -48
  66. package/runtime/plugins/project-orchestrator/runtime/project_maintain.py +241 -204
  67. package/runtime/plugins/project-orchestrator/runtime/project_menu.py +145 -89
  68. package/runtime/plugins/project-orchestrator/runtime/project_real.py +184 -105
  69. package/runtime/plugins/project-orchestrator/runtime/project_write.py +58 -55
  70. package/runtime/plugins/project-orchestrator/runtime/sop.py +1670 -0
  71. package/runtime/plugins/project-orchestrator/runtime/sop_structure.py +226 -0
  72. package/runtime/plugins/project-orchestrator/runtime/wf.py +74 -70
  73. package/runtime/plugins/project-orchestrator/skills/project-orchestrator/SKILL.md +22 -0
  74. package/runtime/plugins/project-orchestrator/sop-templates/blank/SOP.en.md +57 -0
  75. package/runtime/plugins/project-orchestrator/sop-templates/blank/SOP.md +57 -0
  76. package/runtime/plugins/project-orchestrator/sop-templates/knowledge-digest/SOP.en.md +77 -0
  77. package/runtime/plugins/project-orchestrator/sop-templates/knowledge-digest/SOP.md +77 -0
  78. package/runtime/plugins/project-orchestrator/sop-templates/knowledge-digest/templates/digest.en.md +11 -0
  79. package/runtime/plugins/project-orchestrator/sop-templates/knowledge-digest/templates/digest.md +11 -0
  80. package/runtime/plugins/project-orchestrator/sop-templates/video-to-transcript/SOP.en.md +87 -0
  81. package/runtime/plugins/project-orchestrator/sop-templates/video-to-transcript/SOP.md +87 -0
  82. package/runtime/plugins/project-orchestrator/sop-templates/weekly-review/SOP.en.md +75 -0
  83. package/runtime/plugins/project-orchestrator/sop-templates/weekly-review/SOP.md +75 -0
  84. package/runtime/plugins/project-orchestrator/sop-templates/weekly-review/templates/review.en.md +11 -0
  85. package/runtime/plugins/project-orchestrator/sop-templates/weekly-review/templates/review.md +12 -0
  86. package/runtime/plugins/project-orchestrator/templates/CASE.en.md +39 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sakanano-moe/agenthelm",
3
- "version": "6.8.0",
3
+ "version": "6.11.0-rc.1",
4
4
  "description": "agenthelm CLI: install, check and update the agenthelm plugins for Claude Code, Codex and Cursor; a user-level runtime; and a project menu that works without any AI agent.",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -4,14 +4,14 @@
4
4
  "name": "agenthelm",
5
5
  "description": "Cross-agent project management plugins: project contract, lifecycle, extension capabilities and behavior rules. 跨 Agent 的项目管理插件集。",
6
6
  "version": "0.7.0",
7
- "updated_at": "2026-10-27",
7
+ "updated_at": "2026-10-29",
8
8
  "homepage": "./index.html",
9
9
  "domain": "agenthelm.sakanano.moe",
10
10
  "legacy_domain": "skill.sakanano.moe"
11
11
  },
12
12
  "plugin": {
13
13
  "manifest": "./plugins/agents-init/plugin.json",
14
- "version": "6.8.0",
14
+ "version": "6.11.0",
15
15
  "install_unit": "marketplace",
16
16
  "bundled_plugins": [
17
17
  "./plugins/project-orchestrator/plugin.json",
@@ -30,7 +30,7 @@
30
30
  "id": "agents-init",
31
31
  "name": "agents-init v6 / Project Profile initialization and migration",
32
32
  "description": "Create or migrate the project skeleton and root launcher; checks that project-orchestrator, agent-pack and opinion-manager from the same release are present before writing.",
33
- "version": "6.7.0",
33
+ "version": "6.8.0",
34
34
  "status": "stable",
35
35
  "entrypoints": {
36
36
  "browser": "./plugins/agents-init/skills/agents-init/index.html",
@@ -43,7 +43,7 @@
43
43
  "id": "project-orchestrator",
44
44
  "name": "project-orchestrator / project lifecycle orchestration",
45
45
  "description": "Organizes Case workspaces or keeps existing Task/Case layouts; search, lossless migration, verification, scoped Git delivery, and a project menu that works without any AI agent.",
46
- "version": "1.9.0",
46
+ "version": "1.11.1",
47
47
  "status": "stable",
48
48
  "entrypoints": {
49
49
  "agent": "./plugins/project-orchestrator/skills/project-orchestrator/SKILL.md",
@@ -55,7 +55,7 @@
55
55
  "id": "agent-pack",
56
56
  "name": "agent-pack / Agent extension capability management",
57
57
  "description": "Inventory, verify, install, sync, migrate and reconcile Plugins, Skills and MCP between projects and Codex / Cursor / Claude; the agenthelm command line and user-level runtime.",
58
- "version": "1.9.0",
58
+ "version": "1.11.0",
59
59
  "status": "stable",
60
60
  "entrypoints": {
61
61
  "agent": "./plugins/agent-pack/skills/agent-pack/SKILL.md",
@@ -68,7 +68,7 @@
68
68
  "id": "opinion-manager",
69
69
  "name": "opinion-manager / Agent behavior rule management",
70
70
  "description": "Three first-run entry points plus optional memory candidates; one content confirmation, then Profile, body and lock are saved separately, with exact versions and protection of personal edits.",
71
- "version": "0.4.2",
71
+ "version": "0.5.0",
72
72
  "status": "experimental",
73
73
  "entrypoints": {
74
74
  "agent": "./plugins/opinion-manager/skills/opinion-manager/SKILL.md",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-pack",
3
- "version": "1.9.0",
3
+ "version": "1.11.0",
4
4
  "description": "Deterministic Agent-extension capability management for configured workspaces.",
5
5
  "author": {
6
6
  "name": "lc4t"
@@ -10,6 +10,38 @@
10
10
  "timeout": 10
11
11
  }
12
12
  ]
13
+ },
14
+ {
15
+ "matcher": "startup|resume|clear|compact",
16
+ "hooks": [
17
+ {
18
+ "type": "command",
19
+ "command": "python3 \"${CLAUDE_PLUGIN_ROOT}/runtime/agenthelm.py\" nudge hook --event session-start",
20
+ "timeout": 10
21
+ }
22
+ ]
23
+ }
24
+ ],
25
+ "UserPromptSubmit": [
26
+ {
27
+ "hooks": [
28
+ {
29
+ "type": "command",
30
+ "command": "python3 \"${CLAUDE_PLUGIN_ROOT}/runtime/agenthelm.py\" nudge hook --event prompt-submit",
31
+ "timeout": 5
32
+ }
33
+ ]
34
+ }
35
+ ],
36
+ "Stop": [
37
+ {
38
+ "hooks": [
39
+ {
40
+ "type": "command",
41
+ "command": "python3 \"${CLAUDE_PLUGIN_ROOT}/runtime/agenthelm.py\" nudge hook --event stop",
42
+ "timeout": 10
43
+ }
44
+ ]
13
45
  }
14
46
  ]
15
47
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
3
  "name": "agent-pack",
4
- "version": "1.9.0",
4
+ "version": "1.11.0",
5
5
  "description": "Deterministic Agent-extension capability management: inventory, doctor, bootstrap, sync, transfer, and reconcile Agent Plugins / Skills / MCP servers across Codex, Cursor, Claude Code, and project sources. Ships a stdio MCP.",
6
6
  "author": {
7
7
  "name": "lc4t"
@@ -0,0 +1,126 @@
1
+ # 本机专属目录(local-only)
2
+
3
+ 项目放在 iCloud Drive、Dropbox、OneDrive、Google Drive 等同步目录里、在多台设备上使用时,`.venv`、`node_modules`、工具缓存这类**可重建的大目录**不该进同步盘:同步慢、产生冲突副本,不同系统或架构的二进制还会互相覆盖。`agenthelm local-only` 把它们放到每台设备自己的 `~/.local/share/agenthelm/local-only/` 下,在项目里留一个软链接;并能检查出“设备 A 装好了、设备 B 还没装”这类差异。
4
+
5
+ 不在同步目录里的项目不受影响:没有同步服务、也没有 local-only 配置时,`check` 直接返回空结果,不扫描。
6
+
7
+ ## 三条硬约束
8
+
9
+ 1. **链接文本必须在所有设备上相同。** 软链接本身会随项目同步,所以目标路径只由三样东西拼成:项目里记录的 `home`、`project_id`、项目内相对路径——`<home>/.local/share/agenthelm/local-only/<project_id>/<相对路径>`。不读 `XDG_DATA_HOME`。
10
+ 2. **各设备的 HOME 绝对路径必须一致**(例如都是 `/home/<同一个用户名>`)。`home` 记在项目配置里;不一致时 `check` 报“HOME 与项目约定不一致”,`fix` 拒绝建立或修改任何链接。
11
+ 3. **工具只给方案和预览,改文件必须 `--apply`。** 移动失败整体撤销;旧配置先备份到 `~/.agent-pack/recovery/<时间>-agenthelm-local-only/`。
12
+
13
+ ## 怎么处理每一类
14
+
15
+ | 类别 | 例子 | 处理 |
16
+ | --- | --- | --- |
17
+ | 依赖安装物(可外置) | 含 `pyvenv.cfg` 的目录(不管叫什么)、`node_modules`(yarn 经典版、bun、未知管理器) | `fix` 移到本机目录,原位置建软链接 |
18
+ | 依赖安装物(只报告) | `node_modules`(npm、pnpm、yarn 2+)、`.tox`、`.nox`、`.terraform`、`.gradle` | 报告;`.tox` 等没有实测过软链接,确认后可用 `--externalize` 指定 |
19
+ | 工具缓存 | `__pycache__`、`.pytest_cache`、`.mypy_cache`、`.ruff_cache`、`.hypothesis`、`.cache`、`.eslintcache`、`.parcel-cache`、`.turbo`,以及任何带 `CACHEDIR.TAG` 的目录 | 报告并给出环境变量写法,不移动 |
20
+ | 运行中进程的文件 | `*-wal`、`*-shm`、`*.pid`、`*.sock`(`*.lock` 是依赖锁,必须同步,不算) | 只报告 |
21
+ | **默认保持同步** | `dist`、`build`、`out`(构建产物,别的设备不必重新构建)、`.claude`、`.cursor`、`.idea`、`.vscode`(本机工具状态) | 不报告;体积由阈值兜底;可用 `keep_synced` 调整 |
22
+ | 不碰 | `.git`、`.svn`、`.hg` | 不进入 |
23
+
24
+ 识别靠**标记文件**,名字只作兜底:`pyvenv.cfg` 是虚拟环境,`CACHEDIR.TAG` 是工具声明的缓存。“被 git 忽略”只能作候选,不能自动归类——`.env` 也被忽略,但不可重建。
25
+
26
+ ## 实测兼容性
27
+
28
+ 2026-10-29,Linux 容器,软链接指向项目外目录:
29
+
30
+ | 工具 | 结果 |
31
+ | --- | --- |
32
+ | uv 0.11.32 | 正常,链接保留;悬空链接时 `uv sync` 报 `File exists (os error 17)`,先建目标目录即可 |
33
+ | 普通 venv + pip | 正常(脚本里的路径经过链接解析) |
34
+ | yarn 1.22.22、bun 1.4.4 | 正常,重复安装后链接保留 |
35
+ | **npm 10.9.4** | `install` 与 `ci` 都把链接**换成真实目录**(相对、绝对、无变化都一样) |
36
+ | **pnpm 10.28.0** | 安装失败(退出码 236),并删掉了链接目标目录 |
37
+ | `PYTHONPYCACHEPREFIX`、`RUFF_CACHE_DIR`、`MYPY_CACHE_DIR`、`pytest -o cache_dir`、`UV_CACHE_DIR` | 生效,项目内零残留 |
38
+
39
+ 结论:同步目录里的 Node 项目尽量用 **yarn(经典版)或 bun**;npm、pnpm 的 `node_modules` 没有已验证的外置办法,工具只报告,不替你换包管理器(那会改 lock 文件)。项目不在同步目录里时随便用。
40
+
41
+ **未确认**(需要在真机核对,工具不依赖它们给结论):iCloud、Dropbox、OneDrive 是否同步软链接本身;yarn 2+(PnP 或 node-modules 链接方式);iCloud“桌面与文稿”同步的项目路径上看不出来(需要声明 `sync_service`);各服务冲突副本的命名(目前只识别 Dropbox 的 `conflicted copy`、iCloud 的 `.icloud` 占位文件);macOS 上同步状态(是否在同步、账号状态)没有找到可靠的检测办法,工具不报告。
42
+
43
+ ## 命令
44
+
45
+ ```bash
46
+ agenthelm local-only check [--mode quick|standard|full] [--strict] [--output json]
47
+ agenthelm local-only check --fingerprint [--explain 对方的.json]
48
+ agenthelm local-only fix [--externalize 路径]… [--raise-limit 目录=MB[/文件数]]… [--service icloud|dropbox|onedrive|google-drive|syncthing|other|none] [--rebuild] [--apply]
49
+ agenthelm local-only config [--output json]
50
+ ```
51
+
52
+ - `check` 默认 `full`(最多 120 秒);`standard`(6 秒预算)用于 `agenthelm check` / `health`;`quick`(浅层两级目录、不统计体积,1.5 秒)用于会话开始钩子。超过预算会在“说明”里标出只扫了一部分。
53
+ - `check --strict`:有“需要处理”的项时退出码为 1。`agenthelm check --strict` 与会话开始的一行提示也把它们算作未处理。
54
+ - `fix` 不带选项:处理所有推荐项(venv、可外置的 node_modules,以及这台设备上缺失的已声明条目)。首次会创建项目配置。
55
+ - `fix --rebuild`:外置后在本机运行重建命令,由锁文件推断(`uv.lock`→`uv sync`,`poetry.lock`→`poetry install`,`yarn.lock`/`bun.lock(b)`→`install --frozen-lockfile`)。找不到锁文件或工具就跳过。重建失败不撤销外置。
56
+ - 决定(不再提示)沿用 `agenthelm fix --skip <ID> --reason …`;`local:` 开头的 ID 只记在这台机器上。
57
+
58
+ ## 配置
59
+
60
+ 项目配置 `.agents/moe.sakanano.agent-pack/local-only.json`(随项目同步;`fix` 创建,之后你可以手改):
61
+
62
+ ```json
63
+ {
64
+ "schema_version": 1,
65
+ "project_id": "p-5bcae0a8ad",
66
+ "home": "/home/me",
67
+ "sync_service": "icloud",
68
+ "items": [{"path": ".venv", "kind": "venv"}],
69
+ "limits": {
70
+ "warn_ratio": 0.8,
71
+ "dir_mb": 200,
72
+ "dir_files": 20000,
73
+ "overrides": {"docs": {"dir_mb": 1000}}
74
+ },
75
+ "keep_synced": ["dist", "build", "out", ".claude", ".cursor", ".idea", ".vscode"],
76
+ "ignore": ["vendor"],
77
+ "extra_local_only": ["data/cache"]
78
+ }
79
+ ```
80
+
81
+ - `project_id`:由 `home` 与项目路径派生,预览与执行一致;两台设备同时初始化写出相同内容。
82
+ - `sync_service`:声明后不再靠路径猜;`none` 表示不在同步盘里。
83
+ - `limits`:每个**顶层目录**(及项目根的散文件)的体积与文件数阈值;`warn_ratio` 到达阈值的这个比例就开始提示。`overrides` 按目录覆盖。这些数字是默认的启发值,没有任何同步服务的官方限额作依据。
84
+ - `keep_synced`:这些名字(或相对路径)永远不报告,覆盖标记判定。
85
+ - `ignore`:完全不扫描。`extra_local_only`:额外当作本机专属的目录。
86
+ - 用户级覆盖:`~/.config/agenthelm/config.json` 的 `local_only` 段,可写 `limits`、`keep_synced`、`ignore`。优先级:内置默认 < 用户配置 < 项目配置。项目配置优先,是因为阈值会影响各设备得出的结论,应当随项目走。
87
+
88
+ ## 体积快到阈值时
89
+
90
+ 达到 `warn_ratio` 的目录出现一条“接近阈值”的发现(达到阈值则是“需要处理”)。工具不替你选,列出:
91
+
92
+ 1. 确认这个体积正常,提高阈值(`fix --raise-limit 目录=MB/文件数 --apply`,写入项目配置,建议值为现值的 1.25 倍与旧阈值 2 倍中的较大者);
93
+ 2. 不再提示(`fix --skip local:size:<目录> --reason …`,只记在这台机器;状态或阈值变化后会重新提示);
94
+ 3. 在同步服务里把它设为不同步,或移出同步目录(工具不替你做)。
95
+
96
+ 不提供“外置”:普通内容外置后,其他设备看不到它。
97
+
98
+ ## 发现 ID
99
+
100
+ | ID | 含义 | 级别 |
101
+ | --- | --- | --- |
102
+ | `local:sync-folder` | 项目位于同步盘(总览) | 建议 |
103
+ | `local:home-mismatch` | HOME 与项目记录不一致 | 需要处理 |
104
+ | `local:real:<路径>` | 同步目录里有真实的本机专属目录 | 需要处理 |
105
+ | `local:link:<路径>` | 已声明条目的状态:未安装、尚未建立、又变回真实目录、指向别处、被文件占用 | 未安装与尚未建立为建议,其余需要处理 |
106
+ | `local:pm:<目录>` | 同步目录里用 npm 或 pnpm | 建议 |
107
+ | `local:cache` | 带环境变量写法的工具缓存目录(一组) | 建议 |
108
+ | `local:size:<目录>` | 体积接近或超过阈值 | 接近为建议,超过需要处理 |
109
+ | `local:runtime-files` | `-wal`/`-shm`/pid/socket 文件 | 建议 |
110
+ | `local:conflict-copies` | 冲突副本 | 建议 |
111
+ | `local:local-only-config` | 配置有错误(有错误的项不生效) | 建议 |
112
+
113
+ “需要处理”在 `agenthelm check` 的汇总里让 `up_to_date` 变为 false(`--strict` 退出码 1);`health` 里仍是“建议处理”,不改变 `health` 的退出码。
114
+
115
+ ## 多设备流程
116
+
117
+ 1. **设备 A(首次)**:`agenthelm local-only check` 查看;`agenthelm local-only fix` 预览;确认后 `fix --apply`。项目配置和软链接随同步盘到达其他设备。
118
+ 2. **设备 B**:同步完成后运行 `agenthelm local-only check`。软链接在、本机目录不在时报“这台机器还没有安装 …”(此时直接运行 `uv sync` 会报 `File exists`);`fix --apply --rebuild` 建本机目录并按锁文件安装。同步服务不同步软链接时报“尚未建立”,同一条 `fix --apply` 补上。
119
+ 3. **对比**:两台设备各运行 `agenthelm local-only check --fingerprint --output json`,用 `--explain 对方的.json` 看差在哪里(有差异退出码 1)。`agenthelm check --fingerprint` 在项目配置了 local-only 时也带本机环境段,`--explain` 一并比较。指纹只含 HOME、链接状态与链接文本,不含平台和体积——macOS 与 Linux 不同属于正常。
120
+
121
+ ## 给 Agent 的协议
122
+
123
+ - 用 MCP 工具 `agent_pack_cloud_sync_safety_check`(只读)获取发现;不要自己 `mv` / `ln -s` 项目里的目录。
124
+ - `attention: true` 的发现需要告诉用户;每项的 `options` 里有可执行的命令,**移动目录与改配置要用户同意后**再运行 `agenthelm local-only fix … --apply`。
125
+ - 体积类发现必须把选项交给用户决定,不要替用户提高阈值。
126
+ - 项目没有同步服务、也没有配置时工具返回空发现,不要自己提示“需要外置”。
@@ -0,0 +1,58 @@
1
+ # nudge: automatic opinion capture and reminders about unconfirmed items
2
+
3
+ **English** · [简体中文](nudge.md)
4
+
5
+ `agenthelm nudge` is called by the hooks of all three clients so that the opinion mechanism works even when the user does not bring it up: at session start it injects the protocol and the trial rules; during work it reminds the Agent to stash lasting preferences; when a task is done it asks the user to confirm candidates together; and when a new session starts it reports candidates that have been waiting too long, according to thresholds. It only reads and writes opinion-manager's inbox and local machine state, and never writes `OPINION.md`. The inbox and its status flow are described in opinion-manager's `references/inbox.en.md`.
6
+
7
+ ## Behavior per client
8
+
9
+ - **Claude Code**: the plugin ships `hooks/hooks.json`, effective after installation. SessionStart (`startup|resume|clear|compact`) injects the protocol; UserPromptSubmit reminds when a keyword matches; Stop uses `additionalContext` to make the Agent confirm with the user when the conditions are met.
10
+ - **Codex**: reads the same `hooks/hooks.json` (Codex also provides `CLAUDE_PLUGIN_ROOT`). By Codex's rules a plugin hook runs only after the user reviews and trusts it in `/hooks`. Stop uses `decision: "block"` with a `reason`, and the reason text becomes the next turn's continuation prompt.
11
+ - **Cursor**: has no prompt-level injection (`beforeSubmitPrompt` can only allow or block). Run `agenthelm nudge install-hooks --client cursor` to preview and add `--apply` to write sessionStart and stop into `~/.cursor/hooks.json` (`--scope project` writes the project's `.cursor/hooks.json`; `--remove` undoes it and deletes only the entries agenthelm wrote). Cursor's `stop` prompt appears as a "user message", so it is off by default. The community reports cases where sessionStart's `additional_context` does not reach the model (see the Cursor forum), so the protocol is also written in opinion-manager's Skill and can be triggered on demand without the hook.
12
+
13
+ All three clients share these properties: the hook always exits 0 and stays silent on any error; it produces output only in projects that use opinion-manager (the Project Profile's `opinion.provider` is `opinion-manager`, or `.opinion/` or `opinion.lock.json` exists), so other directories never notice it.
14
+
15
+ ## Triggers
16
+
17
+ - **Session start**: always injects the protocol and the full text of trial candidates (up to 6000 characters); after `compact` it only re-injects. When the number of pending candidates reaches `pending_threshold`, or the oldest one is older than `stale_days`, and the last reminder is older than `reminder_repeat_hours`, the user also gets one visible line.
18
+ - **User message**: the message is at most 1500 characters and contains any word from `keywords` (case-insensitive), at most `capture_hints_per_session` reminders per session. Keywords only raise the hit rate; the semantic judgement stays with the Agent. Long messages are mostly pasted content and are skipped.
19
+ - **End of turn**: candidates from this session exist that have not been shown yet, `stop_prompt` allows it, `max_prompts_per_session` is not exceeded and (with `on-completion`) the last reply contains one of `completion_keywords`. Continuation turns (`stop_hook_active`, or Cursor's `loop_count`) never trigger it. The candidates are marked as shown when the request is sent.
20
+
21
+ ## Configuration
22
+
23
+ Locations (later overrides earlier): built-in defaults → the Project Profile's `opinion.nudge` (synced with the project, shared by the team) → the user config `nudge` in `~/.config/agenthelm/config.json` (a personal override). Defaults apply when nothing is set, and the Profile does not need to declare anything. Invalid values are ignored and reported by `agenthelm nudge status`.
24
+
25
+ - `enabled`: default `true`.
26
+ - `language`: message language, `auto` / `zh` / `en`, default `auto`. See the next section.
27
+ - `pending_threshold`: remind when at least this many candidates are pending, default `5`.
28
+ - `stale_days`: remind when the oldest pending candidate is older than this, default `7`.
29
+ - `max_prompts_per_session`: upper limit of end-of-turn confirmation requests per session, default `1`.
30
+ - `capture_hints_per_session`: upper limit of keyword reminders per session, default `3`.
31
+ - `trial_expire_days`: a trial not made formal within this many days returns to pending, default `30`.
32
+ - `reminder_repeat_hours`: shortest interval between visible session-start reminders, default `24`.
33
+ - `stop_prompt`: `off` / `on-completion` / `always`, or per client, default `{"claude": "on-completion", "codex": "on-completion", "cursor": "off"}`.
34
+ - `keywords`, `completion_keywords`: arrays of strings that replace the built-in lists.
35
+
36
+ The environment variable `AGENTHELM_NO_NUDGE=1` temporarily silences all output; `AGENTHELM_NUDGE_DEBUG=1` prints internal hook exceptions to stderr. `agenthelm nudge status [--project P]` shows the effective configuration, the current summary and whether a new session would remind.
37
+
38
+ ## Message language
39
+
40
+ The messages shown to the user and the protocol injected into the model use the same language; Chinese (`zh`) and English (`en`) are supported. The language is decided in this order: the config `nudge.language` (when it is not `auto`) → the environment variable `AGENTHELM_LANG` → the `language` key of the user config `~/.config/agenthelm/config.json` (shared by every agenthelm command) → the system locale (`LC_ALL`, `LC_MESSAGES`, `LANG`) → English. A Chinese locale gets Chinese; a locale of any other language gets English for now; `C` / `POSIX` / empty means "not specified", so the next variable is consulted, and English applies when none names a language. The user config's `nudge.language` overrides the Project Profile, so you can override the team's setting with your own language.
41
+
42
+ - The resolved language is passed on to opinion-manager's `inbox` (`--lang`), so the protocol, the privacy notice, the pending list and the hook messages share one language. The protocol also tells the Agent to relay and confirm in the language the user is using, so the conversation language settles any mismatch with the system language.
43
+ - A candidate's title, rule and the user's quote are the user's own words and are never translated. The keyword lists are data; they contain both Chinese and English by default and can be edited.
44
+ - To add a language, add one entry per message in `MESSAGES` in `runtime/nudge_text.py` and in opinion-manager's `runtime/inbox_text.py`. The tests require every language in each file to have identical keys and placeholders, English text to contain no Chinese, and both files to resolve languages the same way.
45
+
46
+ ## Local machine state
47
+
48
+ Session counters and reminder times are stored in `$XDG_STATE_HOME/agenthelm/nudge.json` (default `~/.local/state`). It holds only session ids and timestamps, for 14 days and at most 200 sessions. The candidates themselves live in the project.
49
+
50
+ ## Verification status
51
+
52
+ Unit tests cover each client's output format, thresholds, rate limits, keywords, config merging and the Cursor hooks.json merge. The following is written from the official documentation and has not yet been verified in real clients: Codex's trust flow for plugin hooks and its `systemMessage` field; Cursor's sessionStart injection and the actual loading of `~/.cursor/hooks.json`; how Claude Code's `Stop` `additionalContext` behaves across versions.
53
+
54
+ ## Privacy: the inbox holds the user's own words
55
+
56
+ The evidence for a candidate is the user's own words, stored in `.opinion/inbox.json` inside the project; they may contain sensitive information (customer names, internal systems, people's names, business details). Projects that use this feature should stay private, or at least stay out of public channels. If you want to make the repository public or place it in a synced or shared folder, whether to exclude `.opinion/` is the user's decision.
57
+
58
+ nudge only reminds and never decides for the user: the first `inbox add` returns a `notice`, each project gets one visible line when its first session starts (nothing is shown when Git already ignores the file), and `agenthelm nudge status` shows the current state at any time. It never edits `.gitignore` and never deletes, rewrites or refuses to store anything.
@@ -0,0 +1,58 @@
1
+ # nudge:自动采集观点候选与未决事项提示
2
+
3
+ [English](nudge.en.md) · **简体中文**
4
+
5
+ `agenthelm nudge` 由三个客户端的 hook 调用,让 opinion 机制在用户不主动提起时也能工作:会话开始注入协议与试行规则,工作中发现长期偏好时提醒 Agent 暂存,任务完成时请用户集中确认,开新会话时按阈值提示久未处理的候选。它只读写 opinion-manager 的收件箱和本机状态,从不写 `OPINION.md`。收件箱与状态流转见 opinion-manager 的 `references/inbox.md`。
6
+
7
+ ## 各客户端的行为
8
+
9
+ - **Claude Code**:插件随附 `hooks/hooks.json`,安装后自动生效。SessionStart(`startup|resume|clear|compact`)注入协议;UserPromptSubmit 在命中关键词时提醒;Stop 在满足条件时用 `additionalContext` 让 Agent 向用户确认。
10
+ - **Codex**:读取同一个 `hooks/hooks.json`(Codex 同时提供 `CLAUDE_PLUGIN_ROOT`)。按 Codex 的规则,插件 hook 需要用户在 `/hooks` 中审阅并信任后才会运行。Stop 使用 `decision: "block"` 加 `reason`,原因文本成为下一轮的续写提示。
11
+ - **Cursor**:没有 prompt 级注入(`beforeSubmitPrompt` 只能放行或拦截)。运行 `agenthelm nudge install-hooks --client cursor` 预览,加 `--apply` 把 sessionStart 与 stop 写入 `~/.cursor/hooks.json`(`--scope project` 写项目的 `.cursor/hooks.json`;`--remove` 撤销,只删除 agenthelm 写入的条目)。Cursor 的 `stop` 提示以“用户消息”的形式出现,默认关闭。社区有 sessionStart 的 `additional_context` 未到达模型的反馈(见 Cursor 论坛),所以协议同时写在 opinion-manager 的 Skill 里,不依赖 hook 也能按需触发。
12
+
13
+ 三个客户端的共同点:hook 永远退出 0,任何异常都静默;只在项目启用了 opinion-manager(Project Profile 的 `opinion.provider` 为 `opinion-manager`,或存在 `.opinion/`、`opinion.lock.json`)时才有输出,其他目录完全无感。
14
+
15
+ ## 触发条件
16
+
17
+ - **会话开始**:总是注入协议与试行候选全文(上限 6000 字符);`compact` 后只重新注入。待确认候选数 ≥ `pending_threshold`,或最久一条超过 `stale_days`,且距上次提示超过 `reminder_repeat_hours` 时,另给用户一行可见提示。
18
+ - **用户消息**:消息 ≤1500 字符且包含 `keywords` 中任一词(不区分大小写),每个会话最多提醒 `capture_hints_per_session` 次。关键词只是提高命中率的辅助,语义判断仍由 Agent 做;长消息多为粘贴内容,跳过。
19
+ - **回合结束**:本会话暂存且没展示过的候选存在、`stop_prompt` 允许、未超过 `max_prompts_per_session`,且(`on-completion` 时)最后一条回复含 `completion_keywords` 之一。续写回合(`stop_hook_active` 或 Cursor 的 `loop_count`)不再触发。发出请求时把这些候选标记为已展示。
20
+
21
+ ## 配置
22
+
23
+ 位置(后者覆盖前者):内置默认 → Project Profile 的 `opinion.nudge`(随项目同步,团队共享)→ 用户配置 `~/.config/agenthelm/config.json` 的 `nudge`(本人覆盖)。缺省即默认值,不要求在 Profile 里声明。非法值被忽略并在 `agenthelm nudge status` 里报告。
24
+
25
+ - `enabled`:默认 `true`。
26
+ - `language`:提示语言,`auto` / `zh` / `en`,默认 `auto`。见下一节。
27
+ - `pending_threshold`:待确认候选 ≥ 此数就提示,默认 `5`。
28
+ - `stale_days`:最久一条待确认候选超过此天数就提示,默认 `7`。
29
+ - `max_prompts_per_session`:每会话回合结束的确认请求上限,默认 `1`。
30
+ - `capture_hints_per_session`:每会话关键词提醒上限,默认 `3`。
31
+ - `trial_expire_days`:试行超过此天数未转正退回待确认,默认 `30`。
32
+ - `reminder_repeat_hours`:会话开始的可见提示最短间隔,默认 `24`。
33
+ - `stop_prompt`:`off` / `on-completion` / `always`,或按客户端设置,默认 `{"claude": "on-completion", "codex": "on-completion", "cursor": "off"}`。
34
+ - `keywords`、`completion_keywords`:字符串数组,替换内置列表。
35
+
36
+ 环境变量 `AGENTHELM_NO_NUDGE=1` 临时关闭全部输出;`AGENTHELM_NUDGE_DEBUG=1` 把 hook 内部异常打印到 stderr。`agenthelm nudge status [--project P]` 显示生效配置、当前汇总以及开新会话是否会提示。
37
+
38
+ ## 提示语言
39
+
40
+ 给用户看的提示和注入给模型的协议使用同一种语言,目前支持中文(`zh`)和英文(`en`)。按这个顺序决定:配置 `nudge.language`(不是 `auto` 时)→ 环境变量 `AGENTHELM_LANG` → 用户配置 `~/.config/agenthelm/config.json` 的 `language`(所有 agenthelm 命令共用)→ 系统 locale(`LC_ALL`、`LC_MESSAGES`、`LANG`)→ 英文。中文 locale 用中文;其他语言的 locale 暂用英文;`C` / `POSIX` / 空值视为未指定,继续看下一个变量,都没有就用英文。用户配置的 `nudge.language` 优先于项目 Profile,所以你可以按自己的语言覆盖团队的设置。
41
+
42
+ - 解析出的语言会传给 opinion-manager 的 `inbox`(`--lang`),所以协议、隐私提醒、待确认列表与 hook 的提示是同一种语言。协议同时要求 Agent 向用户转告和确认时使用用户正在使用的语言,系统语言与对话语言不一致时由对话语言兜底。
43
+ - 候选的标题、规则和用户原话是用户自己的话,从不翻译;关键词列表是数据,默认同时包含中文和英文,可自行增删。
44
+ - 新增语言只需在 `runtime/nudge_text.py` 与 opinion-manager 的 `runtime/inbox_text.py` 的 `MESSAGES` 里为每条文案补一个语言;测试要求每个目录里各语言的键与占位符完全一致,英文文案不得含中文,两处的语言解析规则一致。
45
+
46
+ ## 本机状态
47
+
48
+ 会话计数与提示时间保存在 `$XDG_STATE_HOME/agenthelm/nudge.json`(缺省 `~/.local/state`),只含会话编号和时间戳,保留 14 天、最多 200 个会话。候选本身在项目内。
49
+
50
+ ## 验证状态
51
+
52
+ 单元测试覆盖各客户端的输出格式、阈值、限频、关键词、配置合并和 Cursor hooks.json 合并。以下依据官方文档编写,尚未在真实客户端里逐一验证:Codex 对插件 hook 的信任流程与 `systemMessage` 字段;Cursor 的 sessionStart 注入、`~/.cursor/hooks.json` 的实际加载;Claude Code `Stop` 的 `additionalContext` 在各版本的表现。
53
+
54
+ ## 隐私:收件箱含用户原话
55
+
56
+ 候选的证据是用户的原话,保存在项目内的 `.opinion/inbox.json`,可能含敏感信息(客户名、内部系统、人名、业务细节)。启用本功能的项目建议保持私有,至少不要放进公开渠道。若要公开仓库、放进同步盘或共享目录,是否排除 `.opinion/` 由用户决定。
57
+
58
+ nudge 只提醒,不替用户决定:第一次 `inbox add` 的返回带 `notice`,每个项目第一次开会话时给一行可见提示(已被 Git 忽略则不提醒),`agenthelm nudge status` 随时显示当前状态。它不会修改 `.gitignore`,也不会删除、改写或拒绝保存任何内容。