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.
- package/AGENTS.md +110 -0
- package/DASHBOARD.md +160 -0
- package/PRODUCT.md +113 -0
- package/README.md +403 -0
- package/ally.sh +171 -0
- package/bridge/src/approval-rules.ts +360 -0
- package/bridge/src/channel-delivery.ts +207 -0
- package/bridge/src/channel-types.ts +22 -0
- package/bridge/src/channels/fake/adapter.ts +31 -0
- package/bridge/src/channels/feishu/adapter.ts +411 -0
- package/bridge/src/channels/feishu/approvals.ts +6 -0
- package/bridge/src/channels/feishu/formatter.ts +276 -0
- package/bridge/src/channels/feishu/normalize.ts +368 -0
- package/bridge/src/codex-config.ts +52 -0
- package/bridge/src/config.ts +240 -0
- package/bridge/src/fake-runtime-client.ts +505 -0
- package/bridge/src/handoff-service.ts +494 -0
- package/bridge/src/logger.ts +194 -0
- package/bridge/src/memory-digest.ts +186 -0
- package/bridge/src/receiver-approval-autonomy.ts +158 -0
- package/bridge/src/receiver-control-core.ts +140 -0
- package/bridge/src/receiver-control-work-session.ts +218 -0
- package/bridge/src/receiver-control.ts +83 -0
- package/bridge/src/receiver-delivery.ts +136 -0
- package/bridge/src/receiver-helpers.ts +96 -0
- package/bridge/src/receiver-human-gate.ts +333 -0
- package/bridge/src/receiver-inbound-preflight.ts +162 -0
- package/bridge/src/receiver-recovery.ts +236 -0
- package/bridge/src/receiver-runtime-callbacks.ts +367 -0
- package/bridge/src/receiver-runtime-policy.ts +132 -0
- package/bridge/src/receiver-runtime-state.ts +124 -0
- package/bridge/src/receiver-support-actions.ts +189 -0
- package/bridge/src/receiver-thread-start.ts +57 -0
- package/bridge/src/receiver-turn-coordination.ts +94 -0
- package/bridge/src/receiver-turn-execution.ts +257 -0
- package/bridge/src/receiver-turn-failure.ts +143 -0
- package/bridge/src/receiver-turn-result.ts +185 -0
- package/bridge/src/receiver-turn-steer.ts +70 -0
- package/bridge/src/receiver-work-session.ts +76 -0
- package/bridge/src/receiver.ts +329 -0
- package/bridge/src/router.ts +62 -0
- package/bridge/src/runtime-client-agent-messages.ts +150 -0
- package/bridge/src/runtime-client-message-dispatch.ts +176 -0
- package/bridge/src/runtime-client-protocol.ts +411 -0
- package/bridge/src/runtime-client-request-ops.ts +56 -0
- package/bridge/src/runtime-client-run-turn.ts +158 -0
- package/bridge/src/runtime-client-thread-ops.ts +270 -0
- package/bridge/src/runtime-client-transport.ts +309 -0
- package/bridge/src/runtime-client-turn-poll.ts +224 -0
- package/bridge/src/runtime-client-turn-read.ts +185 -0
- package/bridge/src/runtime-client-turn-state.ts +105 -0
- package/bridge/src/runtime-client.ts +344 -0
- package/bridge/src/runtime-user-input.ts +403 -0
- package/bridge/src/scheduler.ts +239 -0
- package/bridge/src/server-handoff-command.ts +364 -0
- package/bridge/src/server-main.ts +80 -0
- package/bridge/src/server-routine-command.ts +60 -0
- package/bridge/src/server-routine-execution.ts +222 -0
- package/bridge/src/server-runtime-app-support.ts +107 -0
- package/bridge/src/server-runtime-app.ts +238 -0
- package/bridge/src/server-thread-sync-command.ts +63 -0
- package/bridge/src/server.ts +17 -0
- package/bridge/src/session-store-delivery.ts +220 -0
- package/bridge/src/session-store-human-gate.ts +380 -0
- package/bridge/src/session-store-inbound-acceptance.ts +66 -0
- package/bridge/src/session-store-meta.ts +134 -0
- package/bridge/src/session-store-turn-ledger.ts +272 -0
- package/bridge/src/session-store.ts +380 -0
- package/bridge/src/system-notify.ts +220 -0
- package/bridge/src/thread-sync.ts +200 -0
- package/bridge/src/translator.ts +494 -0
- package/bridge/src/types.ts +289 -0
- package/bridge/src/utils.ts +104 -0
- package/bridge/src/work-session-store.ts +471 -0
- package/docs/.gitkeep +0 -0
- package/docs/architecture/codex-feishu-bridge-proposal.md +2742 -0
- package/docs/completed/FEATURE-feishu-markdown-and-reply-support.md +327 -0
- package/docs/completed/README.md +21 -0
- package/docs/completed/SPEC-approval-autonomy-and-safe-defaults.md +205 -0
- package/docs/completed/SPEC-approval-batch-and-strict-reply-shortcuts.md +153 -0
- package/docs/completed/SPEC-conversation-noise-reduction-and-busy-input-gate.md +538 -0
- package/docs/completed/SPEC-engineering-sop-skillization.md +190 -0
- package/docs/completed/SPEC-faithful-bridge-core-thinning-v2.md +376 -0
- package/docs/completed/SPEC-faithful-bridge-core-thinning.md +1071 -0
- package/docs/completed/SPEC-group-chat-sender-identity.md +301 -0
- package/docs/completed/SPEC-middleware-exception-visibility.md +227 -0
- package/docs/completed/SPEC-nightly-memory-digest-visibility.md +121 -0
- package/docs/completed/SPEC-project-group-chat-human-centered-conversation-mapping.md +326 -0
- package/docs/completed/SPEC-remove-cli-persona-bootstrap.md +201 -0
- package/docs/developer-workflow.md +49 -0
- package/docs/implementation/SPEC-codex-same-machine-session-handoff-implementation.md +239 -0
- package/docs/implementation/test-coverage-map.md +363 -0
- package/docs/implementation/work-ally-implementation-guide.md +790 -0
- package/docs/issues/README.md +10 -0
- package/docs/issues/pending/ANALYSIS-ally-premature-recovery-notice-and-task-state-semantics-2026-03-18.md +295 -0
- package/docs/issues/resolved/ANALYSIS-approval-waiting-visible-but-approval-artifact-missing-2026-03-16.md +466 -0
- package/docs/issues/resolved/ANALYSIS-blocking-state-visible-without-user-actionable-artifact-2026-03-16.md +261 -0
- package/docs/issues/resolved/ANALYSIS-codex-app-server-transport-disconnect-semantics-2026-03-14.md +606 -0
- package/docs/issues/resolved/ANALYSIS-premature-terminalization-on-fresh-thread-poll-and-object-error-leak-2026-03-16.md +348 -0
- package/docs/issues/resolved/ANALYSIS-runtime-turn-delivery-and-recovery-2026-03-14.md +603 -0
- package/docs/issues/resolved/ANALYSIS-self-test-gap-approval-waiting-visible-but-approval-artifact-missing-2026-03-16.md +166 -0
- package/docs/issues/resolved/ANALYSIS-self-test-gap-blocking-state-visible-without-user-actionable-artifact-2026-03-16.md +186 -0
- package/docs/issues/resolved/ANALYSIS-self-test-gap-premature-terminalization-on-fresh-thread-poll-and-object-error-leak-2026-03-16.md +166 -0
- package/docs/issues/resolved/REPORT-ally-runtime-turn-delivery-3b42fb8-2026-03-15.md +373 -0
- package/docs/manual-acceptance.md +127 -0
- package/docs/ops-runbook.md +44 -0
- package/docs/planning/FEATURE-memory-system.md +748 -0
- package/docs/planning/SPEC-active-turn-steer-and-context-compaction-visibility.md +269 -0
- package/docs/planning/SPEC-approval-rules-inheritance-and-local-validation-lane.md +450 -0
- package/docs/planning/SPEC-assistant-persona-bootstrap.md +199 -0
- package/docs/planning/SPEC-assistant-rename.md +610 -0
- package/docs/planning/SPEC-bridge-app-server-protocol-alignment.md +667 -0
- package/docs/planning/SPEC-claude-runtime-host-for-work-ally.md +434 -0
- package/docs/planning/SPEC-cli-feishu-codex-session-unification.md +236 -0
- package/docs/planning/SPEC-codex-same-machine-session-handoff.md +873 -0
- package/docs/planning/SPEC-feishu-reaction-shortcuts.md +282 -0
- package/docs/planning/SPEC-local-stable-release-boundary.md +166 -0
- package/docs/planning/SPEC-managed-thread-entry-and-surface-mobility.md +862 -0
- package/docs/planning/SPEC-minimal-bridge-semantics-and-user-visible-surface.md +362 -0
- package/docs/planning/SPEC-npm-alpha-distribution-and-install-first-release.md +222 -0
- package/docs/planning/SPEC-remove-websocket-runtime-transport.md +364 -0
- package/docs/planning/SPEC-runtime-abstraction-phase-1.md +424 -0
- package/docs/planning/SPEC-runtime-connection-and-turn-recovery-semantics.md +274 -0
- package/docs/planning/SPEC-session-presence-and-state-visibility.md +397 -0
- package/docs/planning/SPEC-skill-first-capability-packaging.md +338 -0
- package/docs/planning/SPEC-stable-archive-contract.md +456 -0
- package/docs/planning/SPEC-supervised-start-boundary.md +127 -0
- package/docs/planning/SPEC-user-barrier-reduction-and-activation.md +832 -0
- package/docs/planning/ally-next.md +1278 -0
- package/docs/planning/assistant-workbench-spec.md +725 -0
- package/docs/planning/product-workbench.md +283 -0
- package/docs/product-onboarding.md +227 -0
- package/docs/product-spec-standard.md +528 -0
- package/docs/troubleshooting.md +45 -0
- package/docs/user-quickstart.md +46 -0
- package/internal/dispatch.sh +95 -0
- package/internal/lib/common.sh +1450 -0
- package/internal/modules/assistant/manage.sh +1312 -0
- package/internal/modules/bootstrap/setup.sh +144 -0
- package/internal/modules/config/init-env.sh +10 -0
- package/internal/modules/global/manage.sh +154 -0
- package/internal/modules/handoff/manage.sh +54 -0
- package/internal/modules/mcp/manage.sh +83 -0
- package/internal/modules/ops/logs.sh +76 -0
- package/internal/modules/routines/manage.sh +55 -0
- package/internal/modules/runtime/assistant-autosave.sh +26 -0
- package/internal/modules/runtime/restart.sh +6 -0
- package/internal/modules/runtime/start.sh +283 -0
- package/internal/modules/runtime/status.sh +194 -0
- package/internal/modules/runtime/stop.sh +55 -0
- package/internal/modules/runtime/supervisor.sh +216 -0
- package/internal/modules/runtime/update.sh +26 -0
- package/package.json +41 -0
- package/runtime/config/.gitkeep +0 -0
- package/runtime/host/.gitkeep +0 -0
- package/runtime/host/healthcheck-codex-app-server.ts +22 -0
- package/runtime/host/ping-pong-codex-app-server.ts +66 -0
- package/runtime/host/probe-codex-app-server.ts +115 -0
- package/skills/archive-reader/SKILL.md +9 -0
- package/skills/feishu-production-debug/SKILL.md +37 -0
- package/skills/feishu-production-debug/references/feishu-debug-order.md +49 -0
- package/skills/feishu-production-debug/references/platform-permission-baseline.md +23 -0
- package/skills/issue-to-spec-triage/SKILL.md +44 -0
- package/skills/issue-to-spec-triage/references/triage-rules.md +66 -0
- package/skills/memory-digest/SKILL.md +9 -0
- package/skills/post-implementation-closure/SKILL.md +39 -0
- package/skills/post-implementation-closure/references/closure-checklist.md +45 -0
- package/skills/post-implementation-closure/references/doc-drift-map.md +49 -0
- package/skills/product-spec/SKILL.md +244 -0
- package/templates/env.example +5 -0
- package/templates/routines/nightly-memory-digest.yaml +10 -0
- package/templates/workspace/AGENTS.md +26 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# Feishu Reaction Shortcuts Spec
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
- Target project: `work-ally`
|
|
6
|
+
- Audience: implementation engineer
|
|
7
|
+
- Scope: Feishu channel only
|
|
8
|
+
- Goal: support a small set of emoji reactions as deterministic short-text feedback inputs
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
This spec defines a narrow feature for Feishu reactions:
|
|
13
|
+
|
|
14
|
+
- only a small whitelist of reactions is supported
|
|
15
|
+
- each supported reaction maps to one fixed short text input
|
|
16
|
+
- unsupported reactions are blocked in the bridge layer
|
|
17
|
+
- unsupported reactions trigger a short system reply explaining which reactions are supported
|
|
18
|
+
|
|
19
|
+
This is intentionally not an open-ended intent-recognition feature.
|
|
20
|
+
|
|
21
|
+
The product goal is to let users give very lightweight feedback from Feishu, especially on mobile, without typing a full message.
|
|
22
|
+
|
|
23
|
+
## Problem
|
|
24
|
+
|
|
25
|
+
Feishu supports reacting to a message with an emoji. This is a convenient user action, but `work-ally` currently does not treat reaction events as inbound conversational input.
|
|
26
|
+
|
|
27
|
+
For the intended use case, the important part is not the emoji itself. The important part is the lightweight semantic feedback behind it, for example:
|
|
28
|
+
|
|
29
|
+
- `OK` means “continue”
|
|
30
|
+
- `THUMBSUP` means “agree” or “acknowledged”
|
|
31
|
+
|
|
32
|
+
If we try to interpret all reactions freely, the feature becomes ambiguous and hard to control.
|
|
33
|
+
|
|
34
|
+
So the correct design is to constrain it aggressively.
|
|
35
|
+
|
|
36
|
+
## Product Decision
|
|
37
|
+
|
|
38
|
+
This feature should be implemented as a fixed whitelist of reaction shortcuts.
|
|
39
|
+
|
|
40
|
+
Behavior rules:
|
|
41
|
+
|
|
42
|
+
1. Only reactions in the whitelist are accepted.
|
|
43
|
+
2. Each accepted reaction maps to one fixed short text.
|
|
44
|
+
3. Only reactions placed on assistant-authored messages are handled.
|
|
45
|
+
4. Unsupported reactions do not reach Codex.
|
|
46
|
+
5. Unsupported reactions produce a short system message telling the user which reactions are supported.
|
|
47
|
+
6. Only reaction creation events are handled. Reaction deletion events are ignored.
|
|
48
|
+
|
|
49
|
+
## Non-goals
|
|
50
|
+
|
|
51
|
+
This feature does not attempt to:
|
|
52
|
+
|
|
53
|
+
- infer open-ended user intent from arbitrary emojis
|
|
54
|
+
- support every Feishu emoji
|
|
55
|
+
- preserve reaction IDs in the prompt
|
|
56
|
+
- expose internal message IDs to Codex
|
|
57
|
+
- treat reactions as rich structured prompt objects
|
|
58
|
+
|
|
59
|
+
This is a narrow input shortcut feature, not a general emoji-understanding layer.
|
|
60
|
+
|
|
61
|
+
## Why This Feature Exists
|
|
62
|
+
|
|
63
|
+
### 1. Very low-friction feedback
|
|
64
|
+
|
|
65
|
+
On Feishu mobile, tapping a reaction is faster than typing a message.
|
|
66
|
+
|
|
67
|
+
This is useful for tiny feedback actions such as:
|
|
68
|
+
|
|
69
|
+
- continue
|
|
70
|
+
- confirm
|
|
71
|
+
- acknowledge
|
|
72
|
+
|
|
73
|
+
### 2. Deterministic behavior
|
|
74
|
+
|
|
75
|
+
By limiting the feature to a few explicit mappings, we avoid a fragile “guess the meaning of the emoji” design.
|
|
76
|
+
|
|
77
|
+
### 3. Clear product boundary
|
|
78
|
+
|
|
79
|
+
If a user uses an unsupported emoji, the system should not invent meaning. It should stop at the bridge layer and explain the supported set.
|
|
80
|
+
|
|
81
|
+
## Supported Reaction Set
|
|
82
|
+
|
|
83
|
+
The first version should support only a very small whitelist.
|
|
84
|
+
|
|
85
|
+
Recommended initial mapping:
|
|
86
|
+
|
|
87
|
+
- `OK` -> `继续`
|
|
88
|
+
- `THUMBSUP` -> `认同`
|
|
89
|
+
- `CHECK_MARK` -> `已确认`
|
|
90
|
+
|
|
91
|
+
Exact Feishu emoji type names must be validated against the SDK/platform event payloads during implementation.
|
|
92
|
+
|
|
93
|
+
If the platform uses different canonical names, keep the product meaning the same and normalize the platform names in the adapter layer.
|
|
94
|
+
|
|
95
|
+
## User-Facing Behavior
|
|
96
|
+
|
|
97
|
+
### Supported reaction on an assistant message
|
|
98
|
+
|
|
99
|
+
When a user adds a supported reaction to an assistant-authored message:
|
|
100
|
+
|
|
101
|
+
- the bridge accepts the reaction event
|
|
102
|
+
- the bridge converts it into one fixed short text input
|
|
103
|
+
- that short text is sent into the normal Codex inbound path
|
|
104
|
+
|
|
105
|
+
Examples:
|
|
106
|
+
|
|
107
|
+
- user reacts with `OK` -> Codex receives `继续`
|
|
108
|
+
- user reacts with `THUMBSUP` -> Codex receives `认同`
|
|
109
|
+
- user reacts with `CHECK_MARK` -> Codex receives `已确认`
|
|
110
|
+
|
|
111
|
+
### Unsupported reaction on an assistant message
|
|
112
|
+
|
|
113
|
+
When a user adds an unsupported reaction to an assistant-authored message:
|
|
114
|
+
|
|
115
|
+
- the bridge does not send anything to Codex
|
|
116
|
+
- the bridge sends a short system reply in Feishu, for example:
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
当前只支持这些表情反馈:OK、THUMBSUP、CHECK_MARK。
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Reaction on a non-assistant message
|
|
123
|
+
|
|
124
|
+
If the reaction target was not authored by the assistant:
|
|
125
|
+
|
|
126
|
+
- ignore the event
|
|
127
|
+
- do not send anything to Codex
|
|
128
|
+
- do not send any reply unless product explicitly wants that later
|
|
129
|
+
|
|
130
|
+
## Technical Route
|
|
131
|
+
|
|
132
|
+
## Step 1. Subscribe to Feishu reaction-created events
|
|
133
|
+
|
|
134
|
+
The Feishu adapter currently handles normal message events but not reaction-created events.
|
|
135
|
+
|
|
136
|
+
Implementation should add support for:
|
|
137
|
+
|
|
138
|
+
- `im.message.reaction.created_v1`
|
|
139
|
+
|
|
140
|
+
Reaction deletion events should be ignored in the first version.
|
|
141
|
+
|
|
142
|
+
## Step 2. Verify that the reacted message belongs to the assistant
|
|
143
|
+
|
|
144
|
+
Before mapping the reaction to text, the bridge must verify that the target message was authored by the assistant.
|
|
145
|
+
|
|
146
|
+
This is important because the feature is meant to be a feedback shortcut to the assistant, not a general reaction listener for all chat activity.
|
|
147
|
+
|
|
148
|
+
Recommended implementation pattern:
|
|
149
|
+
|
|
150
|
+
- fetch the target message from Feishu using the reacted message ID
|
|
151
|
+
- inspect sender metadata
|
|
152
|
+
- continue only if the target message is assistant-authored
|
|
153
|
+
|
|
154
|
+
This is an internal bridge concern. Do not expose message IDs to Codex.
|
|
155
|
+
|
|
156
|
+
## Step 3. Normalize supported reactions through a fixed mapping table
|
|
157
|
+
|
|
158
|
+
Implement a small mapping table in the Feishu adapter layer, for example:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
OK -> 继续
|
|
162
|
+
THUMBSUP -> 认同
|
|
163
|
+
CHECK_MARK -> 已确认
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Only exact whitelist entries are accepted.
|
|
167
|
+
|
|
168
|
+
If the reaction emoji is not in the mapping table, treat it as unsupported.
|
|
169
|
+
|
|
170
|
+
## Step 4. Convert supported reactions into plain inbound text
|
|
171
|
+
|
|
172
|
+
For supported reactions, do not build a complex prompt object.
|
|
173
|
+
|
|
174
|
+
Just convert the reaction into a normal short inbound text message and let the rest of the pipeline behave as usual.
|
|
175
|
+
|
|
176
|
+
That means the feature should integrate with the existing receiver path as if the user had typed the mapped phrase manually.
|
|
177
|
+
|
|
178
|
+
## Step 5. Handle unsupported reactions in the bridge, not in Codex
|
|
179
|
+
|
|
180
|
+
Unsupported reactions should never be forwarded to Codex.
|
|
181
|
+
|
|
182
|
+
Instead, the bridge should send a short status/system reply explaining the supported set.
|
|
183
|
+
|
|
184
|
+
This keeps the feature deterministic and avoids sending meaningless emoji events into model context.
|
|
185
|
+
|
|
186
|
+
## Recommended Internal Shape
|
|
187
|
+
|
|
188
|
+
The implementation may synthesize an `InboundMessage` internally for supported reactions, but the synthetic content should remain simple.
|
|
189
|
+
|
|
190
|
+
For example, a supported `OK` reaction may internally become an inbound message whose `text` is simply:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
继续
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
No internal message ID or reaction ID should be included in the text given to Codex.
|
|
197
|
+
|
|
198
|
+
## Prompt Contract
|
|
199
|
+
|
|
200
|
+
Codex should receive only the mapped short text.
|
|
201
|
+
|
|
202
|
+
Examples:
|
|
203
|
+
|
|
204
|
+
- `继续`
|
|
205
|
+
- `认同`
|
|
206
|
+
- `已确认`
|
|
207
|
+
|
|
208
|
+
This is intentionally simple.
|
|
209
|
+
|
|
210
|
+
The bridge should not tell Codex things like:
|
|
211
|
+
|
|
212
|
+
- reaction ID
|
|
213
|
+
- Feishu message ID
|
|
214
|
+
- raw emoji type name unless that is the final user-facing mapped phrase
|
|
215
|
+
|
|
216
|
+
## Acceptance Criteria
|
|
217
|
+
|
|
218
|
+
- `work-ally` listens for Feishu reaction-created events
|
|
219
|
+
- only reactions on assistant-authored messages are eligible for handling
|
|
220
|
+
- supported reactions are mapped deterministically to one fixed short text each
|
|
221
|
+
- supported reactions are forwarded into the normal inbound conversation path as plain text
|
|
222
|
+
- unsupported reactions are blocked before Codex
|
|
223
|
+
- unsupported reactions trigger a short system reply listing the supported reactions
|
|
224
|
+
- reaction deletion events are ignored
|
|
225
|
+
- no internal message IDs are included in Codex prompt input for this feature
|
|
226
|
+
|
|
227
|
+
## Testing Guidance
|
|
228
|
+
|
|
229
|
+
### Unit tests to add or revise
|
|
230
|
+
|
|
231
|
+
- Feishu adapter tests for reaction-created events
|
|
232
|
+
- supported reaction on assistant message -> forwarded as mapped text
|
|
233
|
+
- unsupported reaction on assistant message -> blocked and system reply emitted
|
|
234
|
+
- supported reaction on non-assistant message -> ignored
|
|
235
|
+
- reaction deletion event -> ignored
|
|
236
|
+
|
|
237
|
+
- normalization or helper tests for reaction mapping
|
|
238
|
+
- exact emoji type mapping
|
|
239
|
+
- unsupported emoji fallback path
|
|
240
|
+
|
|
241
|
+
- receiver-level tests if synthetic inbound events are reused
|
|
242
|
+
- mapped text reaches the same turn-processing path as normal user text
|
|
243
|
+
|
|
244
|
+
### Manual verification checklist
|
|
245
|
+
|
|
246
|
+
- react with `OK` to an assistant message and verify the assistant receives `继续`
|
|
247
|
+
- react with `THUMBSUP` to an assistant message and verify the assistant receives `认同`
|
|
248
|
+
- react with `CHECK_MARK` to an assistant message and verify the assistant receives `已确认`
|
|
249
|
+
- react with an unsupported emoji and verify a short support-message is returned
|
|
250
|
+
- react to a user-authored message and verify nothing is forwarded to Codex
|
|
251
|
+
|
|
252
|
+
## Risks And Tradeoffs
|
|
253
|
+
|
|
254
|
+
### 1. Emoji naming mismatch
|
|
255
|
+
|
|
256
|
+
Feishu event payload names may not exactly match the human-facing labels in this spec.
|
|
257
|
+
|
|
258
|
+
Implementation must normalize platform names in the adapter layer and keep product semantics stable.
|
|
259
|
+
|
|
260
|
+
### 2. Chat noise from unsupported reactions
|
|
261
|
+
|
|
262
|
+
If users repeatedly send unsupported reactions, the bridge may emit repeated support messages.
|
|
263
|
+
|
|
264
|
+
The first version can accept this behavior if it remains simple, but the implementation engineer may optionally add lightweight dedupe or cooldown behavior later if needed.
|
|
265
|
+
|
|
266
|
+
### 3. Semantic narrowness is intentional
|
|
267
|
+
|
|
268
|
+
This design deliberately supports only a few fixed meanings. That is a feature, not a bug.
|
|
269
|
+
|
|
270
|
+
The goal is predictable shortcut input, not comprehensive emoji understanding.
|
|
271
|
+
|
|
272
|
+
## Final Recommendation
|
|
273
|
+
|
|
274
|
+
Implement this feature as a strict whitelist-based shortcut system.
|
|
275
|
+
|
|
276
|
+
The product rule should be:
|
|
277
|
+
|
|
278
|
+
- supported reaction on assistant message -> translate to one fixed short text and pass to Codex
|
|
279
|
+
- unsupported reaction -> stop in the bridge and tell the user which reactions are supported
|
|
280
|
+
- reaction on non-assistant message -> ignore
|
|
281
|
+
|
|
282
|
+
This gives `work-ally` a simple, low-risk, high-convenience feedback mechanism without introducing ambiguous emoji interpretation into the assistant pipeline.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# SPEC: 本机 Stable Release 边界
|
|
2
|
+
|
|
3
|
+
状态:Draft / Ready for implementation
|
|
4
|
+
|
|
5
|
+
## 背景
|
|
6
|
+
|
|
7
|
+
`work-ally` 当前既是产品源码仓库,也是日常被 `ally` 命令直接消费的实现体。
|
|
8
|
+
|
|
9
|
+
这在内部打磨阶段会产生一个明确痛点:
|
|
10
|
+
|
|
11
|
+
- 同一台机器上,用户可能同时运行多个 assistant
|
|
12
|
+
- 维护者在源码仓库里直接改代码、联调、自测
|
|
13
|
+
- 但默认 `ally` 入口如果直接指向这份源码,那么别的 assistant 也可能被动吃到未发布改动
|
|
14
|
+
|
|
15
|
+
这会让“开发态”和“稳定使用态”混在一起,伤害默认入口的稳定性。
|
|
16
|
+
|
|
17
|
+
## 问题定义
|
|
18
|
+
|
|
19
|
+
当前缺少一个足够轻量的本地发布边界:
|
|
20
|
+
|
|
21
|
+
- 维护者改源码,不应自动影响默认 `ally` 命令
|
|
22
|
+
- 只有当某版代码已经自测通过、确认可交付时,才应提升为默认稳定版本
|
|
23
|
+
- 用户不应该被迫理解复杂的构建、打包、端口、环境切换概念
|
|
24
|
+
|
|
25
|
+
## 目标
|
|
26
|
+
|
|
27
|
+
1. 给 `ally` 建立一个本机 stable release 概念
|
|
28
|
+
2. 默认 `ally` 入口优先使用 stable release,而不是正在变化的源码树
|
|
29
|
+
3. 维护者在源码树里改完并验证后,可用一个简单动作把当前版本提升为 stable
|
|
30
|
+
4. 已经运行中的 assistant 不因源码仓库变化而被动热切换
|
|
31
|
+
5. `ally status` 能明确显示当前处于 dev 还是 stable,以及对应实现路径
|
|
32
|
+
|
|
33
|
+
## 非目标
|
|
34
|
+
|
|
35
|
+
- 不引入复杂构建系统
|
|
36
|
+
- 不做多版本发布管理 UI
|
|
37
|
+
- 不做远程包仓库或正式安装器
|
|
38
|
+
- 不要求用户理解“编译产物”细节
|
|
39
|
+
- 不在本次解决跨机器升级分发
|
|
40
|
+
|
|
41
|
+
## 设计原则
|
|
42
|
+
|
|
43
|
+
- 优先做“本机稳定副本”,不做重量级打包
|
|
44
|
+
- 优先复用现有 shell / node 运行方式,不引入第二套执行模型
|
|
45
|
+
- 默认稳定,显式发布
|
|
46
|
+
- 用户面对的心智模型尽量简单:
|
|
47
|
+
- 开发者改源码
|
|
48
|
+
- 确认可发后执行 `ally release`
|
|
49
|
+
- 普通 `ally` 继续稳定使用
|
|
50
|
+
|
|
51
|
+
## 方案
|
|
52
|
+
|
|
53
|
+
### 1. 引入 stable release 目录
|
|
54
|
+
|
|
55
|
+
默认 stable release 放在:
|
|
56
|
+
|
|
57
|
+
- `~/.work-ally/releases/stable/`
|
|
58
|
+
|
|
59
|
+
这里存放一份可运行的本机稳定副本。
|
|
60
|
+
|
|
61
|
+
### 2. 默认入口优先使用 stable release
|
|
62
|
+
|
|
63
|
+
默认情况下,`ally` 命令优先解析到 stable release。
|
|
64
|
+
|
|
65
|
+
只有以下场景才显式使用源码树:
|
|
66
|
+
|
|
67
|
+
- 设置了 `WORK_ALLY_SOURCE_DIR`
|
|
68
|
+
- 维护者正在源码树里执行 `ally.sh ...`
|
|
69
|
+
- 维护者执行 `ally release`
|
|
70
|
+
|
|
71
|
+
### 3. 引入显式发布命令
|
|
72
|
+
|
|
73
|
+
新增:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
ally release
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
语义:
|
|
80
|
+
|
|
81
|
+
- 把当前源码树复制为新的 stable release
|
|
82
|
+
- 安装 release 所需依赖
|
|
83
|
+
- 写入最小 release manifest
|
|
84
|
+
- 替换旧的 `stable` 副本
|
|
85
|
+
|
|
86
|
+
这是唯一的“提升默认版本”动作。
|
|
87
|
+
|
|
88
|
+
### 4. 运行态不自动热切换
|
|
89
|
+
|
|
90
|
+
即使执行了 `ally release`:
|
|
91
|
+
|
|
92
|
+
- 已经在运行的 assistant 继续跑当前进程
|
|
93
|
+
- 不自动对整机所有 assistant 做热切换
|
|
94
|
+
- 哪个项目需要切到新版,由维护者显式 `ally restart` 或下次 `ally start` 生效
|
|
95
|
+
|
|
96
|
+
### 5. 状态可见性
|
|
97
|
+
|
|
98
|
+
`ally status` 至少新增:
|
|
99
|
+
|
|
100
|
+
- `release channel`
|
|
101
|
+
- `implementation`
|
|
102
|
+
- 若当前实现来自 stable release,则显示 release manifest 里的:
|
|
103
|
+
- `release updated at`
|
|
104
|
+
- `release source`
|
|
105
|
+
- `release commit`
|
|
106
|
+
- `release source dirty`
|
|
107
|
+
|
|
108
|
+
## 用户路径
|
|
109
|
+
|
|
110
|
+
### 普通用户
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
ally start
|
|
114
|
+
ally status
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
不需要理解源码树或发布目录。
|
|
118
|
+
|
|
119
|
+
### 维护者
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# 1. 在源码树里开发
|
|
123
|
+
npm test
|
|
124
|
+
|
|
125
|
+
# 2. 用源码树联调
|
|
126
|
+
WORK_ALLY_SOURCE_DIR=$PWD ally start
|
|
127
|
+
|
|
128
|
+
# 3. 确认可发
|
|
129
|
+
ally release
|
|
130
|
+
|
|
131
|
+
# 4. 默认 stable ally 生效
|
|
132
|
+
ally status
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 验收标准
|
|
136
|
+
|
|
137
|
+
1. 默认 `ally` 入口优先使用 `~/.work-ally/releases/stable/`
|
|
138
|
+
2. 在源码树里持续改动时,不会自动影响默认 stable 入口
|
|
139
|
+
3. 执行 `ally release` 后,stable release 会被新版本替换
|
|
140
|
+
4. `ally status` 能看到 release channel 与 implementation 路径
|
|
141
|
+
5. stable release 存在 manifest,能追溯来源源码与提交
|
|
142
|
+
6. 文档明确区分开发态与 stable release
|
|
143
|
+
7. shell 回归覆盖默认入口、release 和 status 可见性
|
|
144
|
+
|
|
145
|
+
## 风险与取舍
|
|
146
|
+
|
|
147
|
+
### 风险 1:增加一个“副本目录”概念
|
|
148
|
+
|
|
149
|
+
这是新增概念,但它换来的收益很明确:把“正在开发的源码”与“默认可用版本”隔离开。
|
|
150
|
+
|
|
151
|
+
### 风险 2:用户可能忘记 release
|
|
152
|
+
|
|
153
|
+
这是预期成本,但可以通过文档和 `ally status` 的可见性降低困惑。
|
|
154
|
+
|
|
155
|
+
### 风险 3:stable release 不是严格意义上的编译产物
|
|
156
|
+
|
|
157
|
+
这是刻意取舍。当前阶段不需要重量级 build artifact;一份可运行的本机稳定副本已经足够解决主要痛点。
|
|
158
|
+
|
|
159
|
+
## 结论
|
|
160
|
+
|
|
161
|
+
本期不做复杂 release 系统,只做一个最小闭环:
|
|
162
|
+
|
|
163
|
+
- 源码树持续开发
|
|
164
|
+
- stable release 保持默认稳定
|
|
165
|
+
- `ally release` 作为唯一提升动作
|
|
166
|
+
- `ally status` 负责把当前边界讲清楚
|