work-ally 0.2.0-alpha.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 (172) hide show
  1. package/AGENTS.md +110 -0
  2. package/DASHBOARD.md +160 -0
  3. package/PRODUCT.md +113 -0
  4. package/README.md +403 -0
  5. package/ally.sh +171 -0
  6. package/bridge/src/approval-rules.ts +360 -0
  7. package/bridge/src/channel-delivery.ts +207 -0
  8. package/bridge/src/channel-types.ts +22 -0
  9. package/bridge/src/channels/fake/adapter.ts +31 -0
  10. package/bridge/src/channels/feishu/adapter.ts +411 -0
  11. package/bridge/src/channels/feishu/approvals.ts +6 -0
  12. package/bridge/src/channels/feishu/formatter.ts +276 -0
  13. package/bridge/src/channels/feishu/normalize.ts +368 -0
  14. package/bridge/src/codex-config.ts +52 -0
  15. package/bridge/src/config.ts +240 -0
  16. package/bridge/src/fake-runtime-client.ts +505 -0
  17. package/bridge/src/handoff-service.ts +494 -0
  18. package/bridge/src/logger.ts +194 -0
  19. package/bridge/src/memory-digest.ts +186 -0
  20. package/bridge/src/receiver-approval-autonomy.ts +158 -0
  21. package/bridge/src/receiver-control-core.ts +140 -0
  22. package/bridge/src/receiver-control-work-session.ts +218 -0
  23. package/bridge/src/receiver-control.ts +83 -0
  24. package/bridge/src/receiver-delivery.ts +136 -0
  25. package/bridge/src/receiver-helpers.ts +96 -0
  26. package/bridge/src/receiver-human-gate.ts +333 -0
  27. package/bridge/src/receiver-inbound-preflight.ts +162 -0
  28. package/bridge/src/receiver-recovery.ts +236 -0
  29. package/bridge/src/receiver-runtime-callbacks.ts +367 -0
  30. package/bridge/src/receiver-runtime-policy.ts +132 -0
  31. package/bridge/src/receiver-runtime-state.ts +124 -0
  32. package/bridge/src/receiver-support-actions.ts +189 -0
  33. package/bridge/src/receiver-thread-start.ts +57 -0
  34. package/bridge/src/receiver-turn-coordination.ts +94 -0
  35. package/bridge/src/receiver-turn-execution.ts +257 -0
  36. package/bridge/src/receiver-turn-failure.ts +143 -0
  37. package/bridge/src/receiver-turn-result.ts +185 -0
  38. package/bridge/src/receiver-turn-steer.ts +70 -0
  39. package/bridge/src/receiver-work-session.ts +76 -0
  40. package/bridge/src/receiver.ts +329 -0
  41. package/bridge/src/router.ts +62 -0
  42. package/bridge/src/runtime-client-agent-messages.ts +150 -0
  43. package/bridge/src/runtime-client-message-dispatch.ts +176 -0
  44. package/bridge/src/runtime-client-protocol.ts +411 -0
  45. package/bridge/src/runtime-client-request-ops.ts +56 -0
  46. package/bridge/src/runtime-client-run-turn.ts +158 -0
  47. package/bridge/src/runtime-client-thread-ops.ts +270 -0
  48. package/bridge/src/runtime-client-transport.ts +309 -0
  49. package/bridge/src/runtime-client-turn-poll.ts +224 -0
  50. package/bridge/src/runtime-client-turn-read.ts +185 -0
  51. package/bridge/src/runtime-client-turn-state.ts +105 -0
  52. package/bridge/src/runtime-client.ts +344 -0
  53. package/bridge/src/runtime-user-input.ts +403 -0
  54. package/bridge/src/scheduler.ts +239 -0
  55. package/bridge/src/server-handoff-command.ts +364 -0
  56. package/bridge/src/server-main.ts +80 -0
  57. package/bridge/src/server-routine-command.ts +60 -0
  58. package/bridge/src/server-routine-execution.ts +222 -0
  59. package/bridge/src/server-runtime-app-support.ts +107 -0
  60. package/bridge/src/server-runtime-app.ts +238 -0
  61. package/bridge/src/server-thread-sync-command.ts +63 -0
  62. package/bridge/src/server.ts +17 -0
  63. package/bridge/src/session-store-delivery.ts +220 -0
  64. package/bridge/src/session-store-human-gate.ts +380 -0
  65. package/bridge/src/session-store-inbound-acceptance.ts +66 -0
  66. package/bridge/src/session-store-meta.ts +134 -0
  67. package/bridge/src/session-store-turn-ledger.ts +272 -0
  68. package/bridge/src/session-store.ts +380 -0
  69. package/bridge/src/system-notify.ts +220 -0
  70. package/bridge/src/thread-sync.ts +200 -0
  71. package/bridge/src/translator.ts +494 -0
  72. package/bridge/src/types.ts +289 -0
  73. package/bridge/src/utils.ts +104 -0
  74. package/bridge/src/work-session-store.ts +471 -0
  75. package/docs/.gitkeep +0 -0
  76. package/docs/architecture/codex-feishu-bridge-proposal.md +2742 -0
  77. package/docs/completed/FEATURE-feishu-markdown-and-reply-support.md +327 -0
  78. package/docs/completed/README.md +21 -0
  79. package/docs/completed/SPEC-approval-autonomy-and-safe-defaults.md +205 -0
  80. package/docs/completed/SPEC-approval-batch-and-strict-reply-shortcuts.md +153 -0
  81. package/docs/completed/SPEC-conversation-noise-reduction-and-busy-input-gate.md +538 -0
  82. package/docs/completed/SPEC-engineering-sop-skillization.md +190 -0
  83. package/docs/completed/SPEC-faithful-bridge-core-thinning-v2.md +376 -0
  84. package/docs/completed/SPEC-faithful-bridge-core-thinning.md +1071 -0
  85. package/docs/completed/SPEC-group-chat-sender-identity.md +301 -0
  86. package/docs/completed/SPEC-middleware-exception-visibility.md +227 -0
  87. package/docs/completed/SPEC-nightly-memory-digest-visibility.md +121 -0
  88. package/docs/completed/SPEC-project-group-chat-human-centered-conversation-mapping.md +326 -0
  89. package/docs/completed/SPEC-remove-cli-persona-bootstrap.md +201 -0
  90. package/docs/developer-workflow.md +49 -0
  91. package/docs/implementation/SPEC-codex-same-machine-session-handoff-implementation.md +239 -0
  92. package/docs/implementation/test-coverage-map.md +363 -0
  93. package/docs/implementation/work-ally-implementation-guide.md +790 -0
  94. package/docs/issues/README.md +10 -0
  95. package/docs/issues/pending/ANALYSIS-ally-premature-recovery-notice-and-task-state-semantics-2026-03-18.md +295 -0
  96. package/docs/issues/resolved/ANALYSIS-approval-waiting-visible-but-approval-artifact-missing-2026-03-16.md +466 -0
  97. package/docs/issues/resolved/ANALYSIS-blocking-state-visible-without-user-actionable-artifact-2026-03-16.md +261 -0
  98. package/docs/issues/resolved/ANALYSIS-codex-app-server-transport-disconnect-semantics-2026-03-14.md +606 -0
  99. package/docs/issues/resolved/ANALYSIS-premature-terminalization-on-fresh-thread-poll-and-object-error-leak-2026-03-16.md +348 -0
  100. package/docs/issues/resolved/ANALYSIS-runtime-turn-delivery-and-recovery-2026-03-14.md +603 -0
  101. package/docs/issues/resolved/ANALYSIS-self-test-gap-approval-waiting-visible-but-approval-artifact-missing-2026-03-16.md +166 -0
  102. package/docs/issues/resolved/ANALYSIS-self-test-gap-blocking-state-visible-without-user-actionable-artifact-2026-03-16.md +186 -0
  103. package/docs/issues/resolved/ANALYSIS-self-test-gap-premature-terminalization-on-fresh-thread-poll-and-object-error-leak-2026-03-16.md +166 -0
  104. package/docs/issues/resolved/REPORT-ally-runtime-turn-delivery-3b42fb8-2026-03-15.md +373 -0
  105. package/docs/manual-acceptance.md +127 -0
  106. package/docs/ops-runbook.md +44 -0
  107. package/docs/planning/FEATURE-memory-system.md +748 -0
  108. package/docs/planning/SPEC-active-turn-steer-and-context-compaction-visibility.md +269 -0
  109. package/docs/planning/SPEC-approval-rules-inheritance-and-local-validation-lane.md +450 -0
  110. package/docs/planning/SPEC-assistant-persona-bootstrap.md +199 -0
  111. package/docs/planning/SPEC-assistant-rename.md +610 -0
  112. package/docs/planning/SPEC-bridge-app-server-protocol-alignment.md +667 -0
  113. package/docs/planning/SPEC-claude-runtime-host-for-work-ally.md +434 -0
  114. package/docs/planning/SPEC-cli-feishu-codex-session-unification.md +236 -0
  115. package/docs/planning/SPEC-codex-same-machine-session-handoff.md +873 -0
  116. package/docs/planning/SPEC-feishu-reaction-shortcuts.md +282 -0
  117. package/docs/planning/SPEC-local-stable-release-boundary.md +166 -0
  118. package/docs/planning/SPEC-managed-thread-entry-and-surface-mobility.md +862 -0
  119. package/docs/planning/SPEC-minimal-bridge-semantics-and-user-visible-surface.md +362 -0
  120. package/docs/planning/SPEC-npm-alpha-distribution-and-install-first-release.md +222 -0
  121. package/docs/planning/SPEC-remove-websocket-runtime-transport.md +364 -0
  122. package/docs/planning/SPEC-runtime-abstraction-phase-1.md +424 -0
  123. package/docs/planning/SPEC-runtime-connection-and-turn-recovery-semantics.md +274 -0
  124. package/docs/planning/SPEC-session-presence-and-state-visibility.md +397 -0
  125. package/docs/planning/SPEC-skill-first-capability-packaging.md +338 -0
  126. package/docs/planning/SPEC-stable-archive-contract.md +456 -0
  127. package/docs/planning/SPEC-supervised-start-boundary.md +127 -0
  128. package/docs/planning/SPEC-user-barrier-reduction-and-activation.md +832 -0
  129. package/docs/planning/ally-next.md +1278 -0
  130. package/docs/planning/assistant-workbench-spec.md +725 -0
  131. package/docs/planning/product-workbench.md +283 -0
  132. package/docs/product-onboarding.md +227 -0
  133. package/docs/product-spec-standard.md +528 -0
  134. package/docs/troubleshooting.md +45 -0
  135. package/docs/user-quickstart.md +46 -0
  136. package/internal/dispatch.sh +95 -0
  137. package/internal/lib/common.sh +1450 -0
  138. package/internal/modules/assistant/manage.sh +1312 -0
  139. package/internal/modules/bootstrap/setup.sh +144 -0
  140. package/internal/modules/config/init-env.sh +10 -0
  141. package/internal/modules/global/manage.sh +154 -0
  142. package/internal/modules/handoff/manage.sh +54 -0
  143. package/internal/modules/mcp/manage.sh +83 -0
  144. package/internal/modules/ops/logs.sh +76 -0
  145. package/internal/modules/routines/manage.sh +55 -0
  146. package/internal/modules/runtime/assistant-autosave.sh +26 -0
  147. package/internal/modules/runtime/restart.sh +6 -0
  148. package/internal/modules/runtime/start.sh +283 -0
  149. package/internal/modules/runtime/status.sh +194 -0
  150. package/internal/modules/runtime/stop.sh +55 -0
  151. package/internal/modules/runtime/supervisor.sh +216 -0
  152. package/internal/modules/runtime/update.sh +26 -0
  153. package/package.json +41 -0
  154. package/runtime/config/.gitkeep +0 -0
  155. package/runtime/host/.gitkeep +0 -0
  156. package/runtime/host/healthcheck-codex-app-server.ts +22 -0
  157. package/runtime/host/ping-pong-codex-app-server.ts +66 -0
  158. package/runtime/host/probe-codex-app-server.ts +115 -0
  159. package/skills/archive-reader/SKILL.md +9 -0
  160. package/skills/feishu-production-debug/SKILL.md +37 -0
  161. package/skills/feishu-production-debug/references/feishu-debug-order.md +49 -0
  162. package/skills/feishu-production-debug/references/platform-permission-baseline.md +23 -0
  163. package/skills/issue-to-spec-triage/SKILL.md +44 -0
  164. package/skills/issue-to-spec-triage/references/triage-rules.md +66 -0
  165. package/skills/memory-digest/SKILL.md +9 -0
  166. package/skills/post-implementation-closure/SKILL.md +39 -0
  167. package/skills/post-implementation-closure/references/closure-checklist.md +45 -0
  168. package/skills/post-implementation-closure/references/doc-drift-map.md +49 -0
  169. package/skills/product-spec/SKILL.md +244 -0
  170. package/templates/env.example +5 -0
  171. package/templates/routines/nightly-memory-digest.yaml +10 -0
  172. package/templates/workspace/AGENTS.md +26 -0
package/README.md ADDED
@@ -0,0 +1,403 @@
1
+ # work-ally
2
+
3
+ `work-ally` 是一个把**当前项目**接到**命名 assistant 办公桌 + 官方 Codex runtime**上的薄编排层。
4
+
5
+ 一句话:
6
+
7
+ > `work-ally` 负责让 assistant 带着自己的办公桌进项目工作,但项目本身仍然是项目自己的地盘。
8
+
9
+ 这份 `README.md` 站在**工程维护者 / 后续产品开发者**视角写。
10
+
11
+ 如果你是:
12
+
13
+ - 普通使用者(CLI):先看 `docs/user-quickstart.md`
14
+ - 产品同事:先看 `docs/product-onboarding.md`
15
+ - 日常开发者:再看 `docs/developer-workflow.md`
16
+ - 值班排障:再看 `docs/ops-runbook.md` 与 `docs/troubleshooting.md`
17
+
18
+ ## 文档地图
19
+
20
+ 项目级文档都留在仓库里,不放进 assistant desk。当前可以按这张地图理解:
21
+
22
+ - 门面性文档:只描述当前 shipped model,不记录演进过程。包括 `PRODUCT.md`、`README.md`、`DASHBOARD.md`、`docs/user-quickstart.md`、`docs/product-onboarding.md`
23
+ - 过程性文档:可以保留专题、阶段、取舍与演进轨迹,但不能保留已经失效的现状描述。包括 `docs/implementation/`、`docs/planning/`、`docs/completed/`
24
+
25
+ - `PRODUCT.md`:产品介绍页、边界文档、长期灯塔,回答“这个产品到底是什么、不是什么、为什么存在”。
26
+ - `README.md`:产品定位、当前 shipped model、仓库结构、运行边界、维护入口。
27
+ - `DASHBOARD.md`:产品负责人 / 项目负责人的轻量驾驶舱,回答“现在在做什么、接下来派什么、哪些已经完成”。
28
+ - `docs/architecture/`:灯塔文档与长期架构边界,回答“为什么这样做”。
29
+ - `docs/implementation/`:实施主线、阶段进度、已完成范围,回答“已经做到哪里”。
30
+ - `docs/implementation/test-coverage-map.md`:测试金字塔、MECE 测试域与门禁入口,回答“哪些链路已被自动化覆盖”。
31
+ - `docs/completed/`:已完成专题与已落地 spec,回答“哪些专题已经收口”。
32
+ - `docs/planning/`:feature spec、专项设计稿、下一阶段规划,回答“后面准备做什么”或“哪些点仍待确认”。
33
+ - `docs/product-onboarding.md`:产品同事入场指引,回答“先看什么、按什么顺序看”。
34
+ - `docs/user-quickstart.md`:CLI 用户从零到启动的主路径。
35
+ - `docs/developer-workflow.md`:研发联调、验证入口、日常改动路径。
36
+ - `docs/ops-runbook.md` 与 `docs/troubleshooting.md`:运行、恢复、值班和排障口径。
37
+ - `docs/manual-acceptance.md`:人工验收清单。
38
+
39
+ ## 产品同事先看什么
40
+
41
+ 如果新同事更偏产品、先不看代码,推荐阅读顺序:
42
+
43
+ 1. `PRODUCT.md`:先建立产品边界、存在理由和长期灯塔。
44
+ 2. `README.md`:再建立当前结构、shipped model 与维护入口。
45
+ 3. `DASHBOARD.md`:再快速进入当前工作状态,确认在做什么、谁在做、下一步派什么。
46
+ 4. `docs/architecture/codex-feishu-bridge-proposal.md`:再理解这条产品线的第一性原理与长期架构。
47
+ 5. `docs/implementation/work-ally-implementation-guide.md`:再确认当前主线做到哪一步、哪些已经 shipped。
48
+ 6. `docs/completed/`:先看哪些专题已经收口,再避免重复规划。
49
+ 7. `docs/planning/`:最后看后续规划、存疑点和待推进专题。
50
+ 8. `docs/user-quickstart.md`:最后从当前 CLI 用户路径反看体验和产品暴露面。
51
+
52
+ 阅读旧文档时,若看到和当前实现不一致的历史表述,优先以本 `README.md`、项目 `AGENTS.md`,以及相关文档开头声明的 shipped model 为准。
53
+
54
+ ## 维护者先看什么
55
+
56
+ 先建立这张脑图:
57
+
58
+ - 用户入口只有 `ally.sh`
59
+ - shell 编排主干在 `internal/`
60
+ - bridge 主干在 `bridge/src/`
61
+ - 产品级 Skill 包在 `skills/`
62
+ - 默认安装与升级走 npm(install-first)
63
+ - 官方 Codex runtime 包装在 `runtime/`
64
+ - assistant 长期资产在 `~/.work-ally/assistants/<name>/`
65
+ - 运行期状态、日志、会话都在 assistant desk 的 `.system/`
66
+
67
+ 最常用的维护入口:
68
+
69
+ - 命令分发:`internal/dispatch.sh`
70
+ - 通用路径/状态/Git/锁:`internal/lib/common.sh`
71
+ - assistant setup/remove/config 生成:`internal/modules/assistant/manage.sh`
72
+ - 生命周期控制:`internal/modules/runtime/start.sh`、`internal/modules/runtime/stop.sh`、`internal/modules/runtime/supervisor.sh`、`internal/modules/runtime/status.sh`
73
+ - bridge 启动入口:`bridge/src/server.ts`
74
+ - 入站消息主流程:`bridge/src/receiver.ts`
75
+ - 消息翻译与系统文案:`bridge/src/translator.ts`、`bridge/src/system-notify.ts`
76
+ - Feishu 通道适配:`bridge/src/channels/feishu/adapter.ts`
77
+ - 产品级 skills:`skills/`
78
+
79
+ 当前维护侧常用的工程 Skill:
80
+
81
+ - `skills/product-spec/`:spec draft / refine / review / score
82
+ - `skills/issue-to-spec-triage/`:把需求、问题、抱怨、想法先分诊,再决定是否进入 spec 流
83
+ - `skills/post-implementation-closure/`:实现后做 review、回归、文档同步、状态回写与 commit readiness 收口
84
+ - `skills/feishu-production-debug/`:按生产链路顺序排查 Feishu 消息问题
85
+
86
+ 维护时的默认检查顺序:
87
+
88
+ 1. 先看 `ally status`
89
+ 2. 再看 `ally logs bridge` / `ally logs runtime` / `ally logs supervisor`
90
+ 3. 再确认 assistant desk 的 `.system/runtime/` 与 `.system/archive/` 是否符合预期
91
+ 4. 最后才看 Codex 自己的 `codex-home/` 内部文件
92
+
93
+ ## CLI 用户主路径
94
+
95
+ ```bash
96
+ ally setup <assistant-name> --workspace /path/to/project
97
+ ally start --assistant <assistant-name>
98
+ ally status --assistant <assistant-name>
99
+ ```
100
+
101
+ 这里的 `<assistant-name>` 是你给这位 assistant 起的本机名字,例如 `pm`、`reviewer`、`ally`;它不是固定值。
102
+
103
+ `ally setup <assistant-name> --workspace /path/to/project` 会自动完成:
104
+
105
+ - 创建 assistant 办公桌:`~/.work-ally/assistants/<assistant-name>/`
106
+ - 在办公桌根目录初始化独立 Git 仓库
107
+ - 生成最小配置:`~/.work-ally/assistants/<assistant-name>/.system/config.env`
108
+ - 按默认模板生成 `SOUL.md`
109
+ - 建立项目到 assistant 的绑定记录
110
+ - 准备 assistant 自己的 `CODEX_HOME`
111
+
112
+ 如果后续要调整 assistant 的人格或表达风格,当前稳定公开路径下,直接打开 desk 里的 `SOUL.md` 手动编辑。
113
+
114
+ 用户默认只需要填写:
115
+
116
+ - `FEISHU_APP_ID`
117
+ - `FEISHU_APP_SECRET`
118
+ - 可选:`WORK_ALLY_ALLOWED_USER_IDS`(逗号分隔;留空表示不限制,填写后按白名单严格限制)
119
+ - 可选:`WORK_ALLY_ASSISTANT_GIT_REMOTE`
120
+
121
+ 模型 provider、模型选择、MCP、界面偏好等会参考系统全局 `~/.codex/config.toml` 生成 assistant 自己的初始 `config.toml`;API key 继续走系统环境变量,不写进 assistant 配置文件。
122
+ 另外,assistant 专属 `config.toml` 不会继承全局里其他项目的 trusted 列表,而是强制收敛成当前这一个项目根 `trusted` + 当前这个 assistant desk 根 `trusted`,并固定写入:`sandbox_mode = "workspace-write"`、`approval_policy = "on-request"`、以及 `sandbox_workspace_write.writable_roots = ["<assistant desk>"]`。
123
+
124
+ 命令审批这条链路当前也遵循“优先复用官方能力,不在中间层重造一套”的原则:
125
+
126
+ - `work-ally` 会先自动放行当前项目根 / assistant desk 根内的低风险本地验证动作,例如常见的 `cmake` / `ctest` / `pytest` / `flutter analyze` / `dart test`
127
+ - 若不属于这条本地验证 lane,再去读取官方 Codex 的 `~/.codex/rules/*.rules` 与 assistant-local `<assistant-codex-home>/rules/*.rules`
128
+ - assistant-local rules 只做覆盖层,本地优先于全局
129
+ - 当前实现是只读继承,不维护第二份 remembered-approval 数据库,也不在 bridge 里写 rules
130
+ - rules 采用启动快照;如果你改了全局或 assistant-local rules,重启 assistant 后生效
131
+
132
+ 也就是说,`config.toml` 里通过 `env_key` 引用的 provider 环境变量,必须在你执行 `ally start` 的那个 shell 里可见;缺失时启动会直接失败。
133
+
134
+ 实现本身现在也区分两层:
135
+
136
+ - `ally.sh` 所在源码树:开发态,可随时改动
137
+ - npm 全局安装路径:install-first 运行入口(`ally`)
138
+
139
+ 也就是说,日常开发时你可以直接改仓库源码并联调;对外可安装版本通过 npm alpha 发布与升级,不再依赖本机 stable release 副本。
140
+
141
+ 另外,如果当前 Feishu 机器人还没有发消息权限,或仍处在审核 / 未发布状态,`ally start` 现在会直接失败。
142
+ 这是中间层的显式启动探测,不把“消息都发不出去”的状态误报成已经启动成功。
143
+
144
+ ## 当前 Shipped Model
145
+
146
+ 当前主线已经收口到这几个稳定点:
147
+
148
+ - assistant desk 模型已经落地:`AGENTS.md`、`SOUL.md`、`NOW.md`、`MEMORY.md`、`MISTAKES.md`、`journal/`、`conversations/`
149
+ - 黑匣子稳定原材料已经落到 `.system/archive/`,对话可读视图已经落到 `conversations/`
150
+ - session 运行态已经固定收敛到 `.system/runtime/sessions/`
151
+ - routine / scheduler 底座当前保留给产品内核;暂不把通用“定时任务”作为普通用户主打能力继续外推
152
+ - nightly memory digest 当前只产出 `journal/` 与 `MEMORY.md`,不改写 `NOW.md`
153
+ - nightly memory digest 完成后,如存在可用 Feishu 投递目标,会把本次提炼摘要作为系统消息主动通知用户
154
+ - 新增 capability 已进入 `skill-first` 判断口径:可作为 Skill 包成立的能力,不优先长进 bridge / internal 核心
155
+ - 当前长期边界采用 `Core / Hybrid / Skill` 三分法:桥接真相留 core,内容工作流优先走 Skill 或 Hybrid
156
+ - `ally setup` 会自动准备 desk Git、最小配置文件、assistant 专属 `CODEX_HOME` 与 trusted project 条目
157
+ - managed thread continuity baseline 已通过产品验收:单聊 `/codex`、`/takeover [handle]`、`/threads` 与本机 `ally new|continue|attach|threads --assistant <name>` 围绕独立 `work_session` 工作;严格区分 `runtimeThreadId` 与 `cliResumeRef`,不做摘要复制式伪连续
158
+ - 真实 Codex runtime smoke 在当前环境仍受上游网络请求影响,因此这条线记为“主合同成立”,不记为“真实链路全绿”
159
+ - managed thread continuity 仍保持显式接续语义:如果你要接回官方 Codex CLI 那条独立 work-session,请显式使用 `/takeover`;普通自然语言主路径不再读取 work-session owner
160
+ - 会话降噪与协议对齐已落地:正常路径默认只保留 reaction ack 与真实 runtime 进度,不再补“已收到,开始处理。”或通用 heartbeat;普通自然语言 follow-up 会优先沿 `turn/steer` 进入当前 active turn,只有已对用户可见的审批 / 补充信息阻塞才会在桥层先拦住
161
+ - bridge core thinning V2 已完成:普通自然语言主路径已不再读取 work-session ownership / attached session;work-session 目前只保留在 `/new`、`/takeover`、`/threads`、`/codex` 等显式控制命令路径;session / turn ledger / status surface 已删去一批厚状态字段,bridge core 进一步收回到“最小桥接真相”,且当前 `npm run test:bridge` 已全绿
162
+ - 审批自治边界已落地:当前项目根与 assistant desk 根内的低风险本地验证、自测、改动与提交动作默认自动放行;assistant desk 不只 `.system/`,根目录长期资产也在默认自治边界内
163
+ - 中间层异常透明化已落地:delivery unavailable 与最终仍无法确认的 turn 会明确告知;短暂 recovery、旧 turn 清理与内部 reconciliation 默认继续收回后台
164
+ - 上一轮结果若已产生但当时未稳定送达,bridge 会在下一条 inbound 到来时优先自动补发上一轮结果
165
+
166
+ 当前 runtime 模型固定为:
167
+
168
+ - `supervisor` 常驻托管 `bridge` 与 `assistant-autosave`
169
+ - `bridge` 在本地按需拉起官方 `codex app-server --listen stdio://`
170
+ - `bridge <-> Codex App Server` 之间不再使用独立 listen URL、端口分配或 `runtime-host` 独立后台服务
171
+ - 最终结果以 `thread/read(includeTurns=true)` 与 session / turn ledger 为真相源
172
+
173
+ 推荐继续阅读顺序:
174
+
175
+ 1. 本 README:先建立产品边界、命令口径、目录结构与运行模型
176
+ 2. `docs/developer-workflow.md`:再看研发工作流与常规改动路径
177
+ 3. `docs/ops-runbook.md`:再看启动、重启、恢复、值班处理
178
+ 4. `docs/troubleshooting.md`:最后看典型故障与排查分支
179
+
180
+ ## 核心边界
181
+
182
+ - `ally.sh` 是唯一用户入口
183
+ - `skills/` 承接机制性 workflow,不承接主身份;不要把它们继续写回 bridge core
184
+ - 发布入口为 npm alpha:`npm publish --tag alpha`(由 `npm run release:alpha` 统一执行)
185
+ - 当前项目目录只承载项目代码与项目级 `AGENTS.md`
186
+ - assistant 的身份、记忆、对话、运行态都进入 assistant 办公桌
187
+ - 项目目录默认不会生成 `.work-ally/` 运行目录
188
+ - 一个运行中的 ally 进程对应一个 assistant 办公桌
189
+ - 同一个 assistant 不能同时跑在两个项目中
190
+ - 同一个 Feishu bot/app 不能同时被两个项目占用
191
+ - Feishu 普通最终回复默认走 Markdown-rich 渲染(普通内容走 `post`,表格/系统消息走 `interactive`)
192
+ - Feishu reply 消息会自动提取被回复消息正文,并以 best-effort 方式带入 prompt 上下文
193
+ - Feishu 群聊现已支持极简闭环:依赖飞书平台正确权限配置,仅处理群里显式 `@` 机器人的消息;如果配置了 allowlist,则只接受白名单内用户
194
+ - 同一 assistant 在 Feishu 私聊与项目群里 `@` 是同一个角色入口,但会按 `conversationId` 落到两条独立 thread
195
+ - 飞书平台最小权限前提已收口为三项:开启“读取用户发给机器人的单聊消息”、开启“接收群聊中@机器人消息事件”、不要开启“获取群组中所有消息(敏感权限)”
196
+ - Skill 第一阶段只信任仓库内或用户自管的本地内容;当前不做远程 Skill market,不自造第二套插件平台
197
+
198
+ ## 办公桌结构
199
+
200
+ 默认目录:
201
+
202
+ - `~/.work-ally/assistants/<name>/`
203
+
204
+ 用户可见内容:
205
+
206
+ - `AGENTS.md`
207
+ - `SOUL.md`
208
+ - `NOW.md`
209
+ - `MEMORY.md`
210
+ - `MISTAKES.md`
211
+ - `journal/`
212
+ - `conversations/`
213
+
214
+ 内部系统目录:
215
+
216
+ - `.system/config.env`
217
+ - `.system/codex-home/`
218
+ - `.system/runtime/`
219
+ - `.system/logs/`
220
+ - `.system/runs/`
221
+ - `.system/cache/`
222
+ - `.system/routines/`
223
+ - `.system/archive/`
224
+
225
+ 说明:
226
+
227
+ - `AGENTS.md` 是 desk 侧稳定规则与加载器
228
+ - `SOUL.md` 是助理的人格、名字、风格和做事方式
229
+ - `ally setup` 会预填一版通用 `SOUL.md`:中文优先、亲切直接、IM 短回复、先结论后补充、像给领导过目的简洁汇报;后续如果你要改人格,直接编辑 desk 里的 `SOUL.md`
230
+ - `NOW.md` 是当前态便签,由 assistant 工作中主动更新
231
+ - `MEMORY.md` 是长期记忆
232
+ - `MISTAKES.md` 是错题本
233
+ - `journal/` 是按天整理的工作日记
234
+ - `conversations/` 是对话可读视图层
235
+ - `.system/archive/` 是稳定原材料层,不是默认阅读界面
236
+ - `.system/` 只放实现层与运行层所需的内部材料
237
+
238
+ ## Git 自动存档
239
+
240
+ assistant 办公桌默认开启 Git:
241
+
242
+ - 初始化时 `git init`
243
+ - `ally start` 时 checkpoint
244
+ - 后台 autosave 定时 checkpoint
245
+ - `ally stop` 时 checkpoint
246
+ - 配置远端后才会自动 push
247
+
248
+ 这套 Git 仓库位于 assistant 办公桌根目录,不在项目仓库里面,因此不会和宿主项目的 Git 冲突。
249
+
250
+ 默认会进入版本历史的是 assistant 的可见长期资产,以及 `.system/archive/` / `.system/routines/` 这类稳定材料;`.system/runtime/`、`.system/logs/`、`.system/cache/`、`.system/runs/`、`config.env`、以及 Codex 生成的 SQLite / snapshot / skills / tmp 内部文件不会进入版本库。
251
+
252
+ ## Feishu 侧当前默认行为
253
+
254
+ - 普通最终回复:默认发送 Markdown-rich 消息,而不是纯文本降级
255
+ - 表格 / 系统消息:继续走 card 路径
256
+ - 用户输入提示 / 补充信息请求:仍保持纯文本,避免交互噪音
257
+ - 用户在 Feishu 里直接“回复某条 AI 消息”时:ally 会尝试抓取被回复消息正文,再把这段正文带进本轮上下文
258
+ - 在 Feishu 群聊里:只支持显式 `@` 机器人触发;普通群聊消息、reply assistant、以及裸控制命令都不作为正式支持路径
259
+ - 长耗时处理中,如果 runtime 有中间进度文本,会优先按 Codex 的完整 item 边界回传“工作进展”弱提示卡;正常路径默认不再频繁补“正在处理 / 正在思考中”这类通用噪音,只有确有必要时才保留最小兜底
260
+ - 需要审批时,Feishu 会发审批卡,里面会写清楚审批类型、动作、影响范围与原因;当前项目根与 assistant desk 根内的低风险本地验证、自测、改动和提交动作默认静默放行,高风险边界才继续要求人工拍板;当会话正在等审批时,你下一条消息若严格等于 `OK` / `同意` / `NO` / `拒绝`,会直接作为审批处理,不需要特地 reply 某张卡;若同一轮出现多项审批,前台会默认合并成一张卡;也仍可用 `/approve <id>` / `/deny <id>` 兜底
261
+ - 最终结果默认由 `bridge` 主动对账 turn 终态;如果某一轮状态暂时无法确认,用户侧看到的是任务语义文案,而不是实现层的断开 / 重连术语
262
+ - 如果上一轮结果其实已经产生但当时未稳定送达,bridge 会在你下一条消息到来时优先自动补发上一轮结果
263
+ - 后台默认由 `supervisor` 常驻托管 `bridge` 与 `assistant-autosave`;Codex runtime 由 `bridge` 在本地以 stdio child-process 方式按需拉起并托管
264
+
265
+ 群聊使用口径可以直接理解为:
266
+
267
+ - `@ally ...`:会触发
268
+ - 普通群聊消息:不会触发
269
+ - reply assistant 后继续追问:当前不作为支持路径
270
+ - 群里裸 `/status`:当前不作为支持路径
271
+ - reply 其他人的消息:不会触发
272
+
273
+ 另外:
274
+
275
+ - 一个 assistant 对应一个独立飞书机器人身份
276
+ - 私聊和群聊 `@` 都是在找同一位 assistant,但会进入各自独立的 thread
277
+ - 飞书平台最小权限必须配对:开启“读取用户发给机器人的单聊消息”、开启“接收群聊中@机器人消息事件”、不要开启“获取群组中所有消息(敏感权限)”
278
+
279
+ 如果 `WORK_ALLY_ALLOWED_USER_IDS` 为空,则不额外限制发送者;一旦填写,就只接受列表里的用户。
280
+
281
+ ## 启动后先看什么
282
+
283
+ 建议 `ally start --assistant <name>` 后立刻跑一次:
284
+
285
+ ```bash
286
+ ally status --assistant <name>
287
+ ```
288
+
289
+ 至少确认这些字段正常:
290
+
291
+ - `assistant: <你的名字>`
292
+ - `assistant home: ...`
293
+ - `assistant codex home: ...`
294
+ - `assistant lock status: owned`
295
+ - `supervisor: running (...)`
296
+ - `bridge: running (...)`
297
+ - `assistant autosave: running (...)`
298
+
299
+ ## 命令作用域口径
300
+
301
+ 建议把命令分成两类来理解:
302
+
303
+ - **assistant 作用域命令**:显式控制某个命名 assistant,可在任意目录执行
304
+ - **机器作用域命令**:查看或控制“这台机器上所有正在运行的 ally 实例”
305
+
306
+ assistant 作用域命令包括:
307
+
308
+ - `ally start --assistant <name>`
309
+ - `ally stop --assistant <name>`
310
+ - `ally restart --assistant <name>`
311
+ - `ally status --assistant <name>`
312
+ - `ally logs ... --assistant <name>`
313
+ - `ally mcp ... --assistant <name>`
314
+ - `ally routine ... --assistant <name>`
315
+
316
+ 当某个 workspace 只绑定了一个 assistant 时,仍可保留最小隐式推断;但一旦同一项目绑定了多个 assistant,就必须显式带 `--assistant`。
317
+
318
+ 机器作用域命令目前主要是:
319
+
320
+ - `ally global list`
321
+ - `ally global stop --assistant <name>`
322
+ - `ally global stop --pid <pid>`
323
+
324
+ ## 查看 assistant
325
+
326
+ 如果你要看“这台电脑上已经建过 / 注册过哪些 assistant”,先用:
327
+
328
+ ```bash
329
+ ally assistant list
330
+ ```
331
+
332
+ 如果你要看“当前有几个 assistant 正在运行”,再用:
333
+
334
+ ```bash
335
+ ally global list
336
+ ```
337
+
338
+ 也就是说:
339
+
340
+ - `assistant list` 看已注册 assistant
341
+ - `global list` 看当前运行中的 assistant 实例
342
+
343
+ ## 维护改动最容易漏什么
344
+
345
+ 后续维护时,优先记住这几个同步点:
346
+
347
+ - 改命令语义:同步 `README.md`、`docs/user-quickstart.md`
348
+ - 改 bridge 行为:至少补对应 unit / integration test,并回看 `docs/implementation/test-coverage-map.md` 的对应测试域
349
+ - 改 shell 生命周期:至少跑 `bash -n` 和 `tests/shell/assistant.sh`
350
+ - 改 assistant desk 结构:同步 README 里的“办公桌结构”与相关 quickstart / troubleshooting
351
+ - 改审批、心跳、恢复、系统提示:同步用户文案与排障文档
352
+
353
+ ## 常用命令
354
+
355
+ ```bash
356
+ ally setup <assistant-name> --workspace /path/to/project
357
+ ally start --assistant <assistant-name>
358
+ ally status --assistant <assistant-name>
359
+ npm run release:alpha
360
+ ally stop --assistant <assistant-name>
361
+ ally restart --assistant <assistant-name>
362
+ ally assistant list
363
+ ally assistant show <name>
364
+ ally assistant rename <old> <new>
365
+ ally assistant remove <name>
366
+ ally logs timeline --assistant <assistant-name>
367
+ ally routine list --assistant <assistant-name>
368
+ ally global list
369
+ ```
370
+
371
+ ## `ally status` 重点项
372
+
373
+ 至少应看到:
374
+
375
+ - `assistant`
376
+ - `assistant home`
377
+ - `assistant codex home`
378
+ - `assistant autosave`
379
+ - `assistant lock status`
380
+ - `channel lock status`
381
+ - `workspace`
382
+ - `supervisor`
383
+ - `bridge`
384
+
385
+ ## Assistant 改名
386
+
387
+ ```bash
388
+ ally assistant rename <old> <new>
389
+ ```
390
+
391
+ 这是一次受控迁移:会同步更新 assistant registry、project registry、desk 路径、`.system/config.env`、runtime `assistant.env`、stale lock,以及 managed thread continuity 使用的 work-session 索引与元数据。rename 完成后,旧名字不再是正式控制入口。
392
+
393
+ rename 只会在 assistant 已停止,且没有被外部 surface 持有 active work session 时成功。
394
+
395
+ ## 删除 assistant
396
+
397
+ ```bash
398
+ ally assistant remove <name>
399
+ ```
400
+
401
+ 这个命令会同时删除 assistant 办公桌、assistant 注册记录,以及所有指向该 assistant 的项目映射。
402
+
403
+ 这是危险操作,必须连续输入三次 `YES`。如果 assistant 仍在运行,删除会被拒绝。
package/ally.sh ADDED
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ resolve_script_path() {
5
+ local source="$1"
6
+ while [ -h "$source" ]; do
7
+ local dir target
8
+ dir=$(cd -P "$(dirname "$source")" && pwd)
9
+ target=$(readlink "$source")
10
+ case "$target" in
11
+ /*)
12
+ source="$target"
13
+ ;;
14
+ *)
15
+ source="$dir/$target"
16
+ ;;
17
+ esac
18
+ done
19
+
20
+ local dir
21
+ dir=$(cd -P "$(dirname "$source")" && pwd)
22
+ printf '%s/%s\n' "$dir" "$(basename "$source")"
23
+ }
24
+
25
+ discover_workspace_root() {
26
+ if [ -n "${WORK_ALLY_WORKSPACE_ROOT:-}" ]; then
27
+ (cd "$WORK_ALLY_WORKSPACE_ROOT" && pwd)
28
+ return 0
29
+ fi
30
+
31
+ local start dir stop_at
32
+ start=$(cd "$PWD" && pwd)
33
+ dir="$start"
34
+ stop_at="${LOCAL_IMPLEMENTATION_ROOT:-}"
35
+
36
+ while :; do
37
+ if [ "$dir" != "$stop_at" ] && [ -d "$dir/.git" ]; then
38
+ printf '%s\n' "$dir"
39
+ return 0
40
+ fi
41
+
42
+ if [ "$dir" = "/" ]; then
43
+ break
44
+ fi
45
+
46
+ if [ -n "$stop_at" ] && [ "$dir" = "$stop_at" ]; then
47
+ break
48
+ fi
49
+
50
+ dir=$(dirname "$dir")
51
+ done
52
+
53
+ printf '%s\n' "$start"
54
+ }
55
+
56
+ SCRIPT_PATH=$(resolve_script_path "${BASH_SOURCE[0]}")
57
+ SCRIPT_DIR=$(cd "$(dirname "$SCRIPT_PATH")" && pwd)
58
+ INVOKED_NAME=$(basename "$0")
59
+ BOOTSTRAP_ENV_FILE="${WORK_ALLY_BOOTSTRAP_ENV_FILE:-$SCRIPT_DIR/.ally-dev.env}"
60
+
61
+ if [ -f "$BOOTSTRAP_ENV_FILE" ]; then
62
+ set -a
63
+ # shellcheck disable=SC1090
64
+ . "$BOOTSTRAP_ENV_FILE"
65
+ set +a
66
+ fi
67
+
68
+ IMPL_SUBDIR_DEFAULT="work-ally"
69
+ IMPL_SUBDIR="${WORK_ALLY_IMPLEMENTATION_SUBDIR:-$IMPL_SUBDIR_DEFAULT}"
70
+ SOURCE_DIR="${WORK_ALLY_SOURCE_DIR:-}"
71
+ DEV_SOURCE_DIR="${WORK_ALLY_DEV_SOURCE_DIR:-}"
72
+ LOCAL_DISPATCH="$SCRIPT_DIR/internal/dispatch.sh"
73
+ LOCAL_IMPLEMENTATION_ROOT=""
74
+
75
+ if [ -x "$LOCAL_DISPATCH" ]; then
76
+ LOCAL_IMPLEMENTATION_ROOT="$SCRIPT_DIR"
77
+ fi
78
+
79
+ WORKSPACE_ROOT="${WORK_ALLY_WORKSPACE_ROOT:-$(discover_workspace_root)}"
80
+ STATE_DIR="${WORK_ALLY_STATE_DIR:-}"
81
+ CMD_NAME="${WORK_ALLY_CMD_NAME:-$INVOKED_NAME}"
82
+
83
+ usage() {
84
+ cat <<USAGE
85
+ Usage: $CMD_NAME <command> [args]
86
+
87
+ Commands:
88
+ setup [assistant scope] Create or bind an assistant to a project path
89
+ assistant <subcmd> [global scope] Manage named assistant profiles
90
+ start [assistant scope] Start a named assistant from anywhere
91
+ stop [assistant scope] Stop a named assistant from anywhere
92
+ restart [assistant scope] Restart a named assistant from anywhere
93
+ status [assistant scope] Show status for a named assistant
94
+ logs [timeline|bridge|runtime|routine] [follow|print|--tail N]
95
+ [assistant scope] View logs for a named assistant
96
+ update [assistant scope] Show npm-based update guidance
97
+ codex [assistant scope] Launch official Codex CLI with assistant-bound profile
98
+ new [assistant scope] Start a new managed Codex thread in the assistant desk
99
+ continue [assistant scope] Continue a managed Codex thread from the assistant desk
100
+ attach [assistant scope] Attach an existing assistant-scoped Codex thread
101
+ threads [assistant scope] List managed threads for an assistant
102
+ handoff <subcmd> [assistant scope] Compatibility wrapper for Codex thread handoff commands
103
+ mcp <subcmd> [assistant scope] Manage Codex MCP integrations (currently Feishu docs)
104
+ routine <subcmd> [assistant scope] Manage proactive routines for a named assistant
105
+ thread-sync [assistant scope] Pull full conversation history from active thread(s)
106
+ global <subcmd> [machine scope] Show/stop running ally instances across assistants
107
+ help Show this help
108
+ USAGE
109
+ }
110
+
111
+ resolve_impl_dir() {
112
+ local root="$1"
113
+ if [ -x "$root/internal/dispatch.sh" ]; then
114
+ printf '%s\n' "$root"
115
+ return 0
116
+ fi
117
+ if [ -n "$IMPL_SUBDIR" ] && [ -x "$root/$IMPL_SUBDIR/internal/dispatch.sh" ]; then
118
+ printf '%s\n' "$root/$IMPL_SUBDIR"
119
+ return 0
120
+ fi
121
+ return 1
122
+ }
123
+
124
+ ensure_implementation() {
125
+ local source_override resolved_source
126
+ source_override="${SOURCE_DIR:-${DEV_SOURCE_DIR:-}}"
127
+
128
+ if [ -n "$source_override" ]; then
129
+ resolved_source=$(resolve_impl_dir "$source_override") || {
130
+ echo "✗ WORK_ALLY_SOURCE_DIR does not contain a valid implementation: $source_override" >&2
131
+ exit 1
132
+ }
133
+ export WORK_ALLY_INSTALL_ROOT="$source_override"
134
+ export WORK_ALLY_IMPLEMENTATION_DIR="$resolved_source"
135
+ export WORK_ALLY_INSTALL_CHANNEL="source"
136
+ return 0
137
+ fi
138
+
139
+ if [ -x "$LOCAL_DISPATCH" ]; then
140
+ export WORK_ALLY_INSTALL_ROOT="$SCRIPT_DIR"
141
+ export WORK_ALLY_IMPLEMENTATION_DIR="$SCRIPT_DIR"
142
+ export WORK_ALLY_INSTALL_CHANNEL="source_checkout"
143
+ return 0
144
+ fi
145
+
146
+ resolved_source=$(resolve_impl_dir "$SCRIPT_DIR") || {
147
+ echo "✗ work-ally implementation not found beside this entrypoint." >&2
148
+ echo " Reinstall from npm or run with WORK_ALLY_SOURCE_DIR=<repo-root>." >&2
149
+ exit 1
150
+ }
151
+ export WORK_ALLY_INSTALL_ROOT="$SCRIPT_DIR"
152
+ export WORK_ALLY_IMPLEMENTATION_DIR="$resolved_source"
153
+ export WORK_ALLY_INSTALL_CHANNEL="installed"
154
+ }
155
+
156
+ CMD="${1:-help}"
157
+ case "$CMD" in
158
+ help|-h|--help)
159
+ usage
160
+ exit 0
161
+ ;;
162
+ global|handoff|codex|new|continue|attach|threads|thread-sync)
163
+ export WORK_ALLY_SKIP_STATE_BOOTSTRAP=1
164
+ ;;
165
+ esac
166
+
167
+ ensure_implementation
168
+ export WORK_ALLY_CMD_NAME="$CMD_NAME"
169
+ export WORK_ALLY_WORKSPACE_ROOT="$WORKSPACE_ROOT"
170
+ export WORK_ALLY_STATE_DIR="$STATE_DIR"
171
+ exec "$WORK_ALLY_IMPLEMENTATION_DIR/internal/dispatch.sh" "$@"