feishu-codex-connector 0.1.6
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/LICENSE +21 -0
- package/README.md +169 -0
- package/README.zh.md +170 -0
- package/bin/feishu-codex.mjs +8 -0
- package/dist/chunk-AOVT2UMM.js +3876 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +454 -0
- package/dist/index.d.ts +994 -0
- package/dist/index.js +144 -0
- package/docs/ARCHITECTURE.md +691 -0
- package/docs/COMMAND_COMPLETION_SPEC.md +92 -0
- package/docs/FEATURE_PARITY_SPEC.md +104 -0
- package/docs/FEISHU_PERMISSIONS.md +24 -0
- package/docs/SPEC.md +825 -0
- package/package.json +93 -0
package/docs/SPEC.md
ADDED
|
@@ -0,0 +1,825 @@
|
|
|
1
|
+
# Feishu Codex Connector Functional Specification
|
|
2
|
+
|
|
3
|
+
## 1. Scope
|
|
4
|
+
|
|
5
|
+
This specification defines the first implementation target for `feishu-codex-connector`: a Codex-only connector controlled from Feishu/Lark.
|
|
6
|
+
|
|
7
|
+
The first version must feel complete for a single owner, a small team, and a project group:
|
|
8
|
+
|
|
9
|
+
- Start and manage the bridge locally or as a background service.
|
|
10
|
+
- Bind a Feishu/Lark app.
|
|
11
|
+
- Receive private, group, topic, card, and document-comment inputs.
|
|
12
|
+
- Run Codex in a selected workspace.
|
|
13
|
+
- Stream output back to the user through rich run cards by default.
|
|
14
|
+
- Preserve session continuity.
|
|
15
|
+
- Enforce access, workspace, sandbox, callback, and attachment policies.
|
|
16
|
+
- Support Codex API key authentication without requiring interactive Codex login on the host.
|
|
17
|
+
- Expose profile-local Feishu/Lark CLI identity to Codex when configured.
|
|
18
|
+
|
|
19
|
+
## 2. Product Personas
|
|
20
|
+
|
|
21
|
+
### 2.1 Owner
|
|
22
|
+
|
|
23
|
+
The person who creates or owns the Feishu/Lark app. The owner can:
|
|
24
|
+
|
|
25
|
+
- Use the bot in private chats and groups.
|
|
26
|
+
- Manage access lists.
|
|
27
|
+
- Change configuration.
|
|
28
|
+
- Run diagnostics.
|
|
29
|
+
- Stop or restart connector processes.
|
|
30
|
+
|
|
31
|
+
### 2.2 Admin
|
|
32
|
+
|
|
33
|
+
A trusted maintainer added by the owner. An admin can:
|
|
34
|
+
|
|
35
|
+
- Use private chat.
|
|
36
|
+
- Use the bot in any group where access policy permits admin bypass.
|
|
37
|
+
- Manage workspaces and access.
|
|
38
|
+
- Run diagnostics and lifecycle commands.
|
|
39
|
+
|
|
40
|
+
### 2.3 Allowed User
|
|
41
|
+
|
|
42
|
+
A user explicitly allowed to use the bot in private chat or in an allowed group. An allowed user can:
|
|
43
|
+
|
|
44
|
+
- Send ordinary Codex tasks.
|
|
45
|
+
- Stop their current run.
|
|
46
|
+
- Reset or resume their own scope.
|
|
47
|
+
|
|
48
|
+
### 2.4 Group Member
|
|
49
|
+
|
|
50
|
+
A member of an allowed group. They can use the bot only according to group mention policy.
|
|
51
|
+
|
|
52
|
+
## 3. Profile and Runtime Management
|
|
53
|
+
|
|
54
|
+
### V1 Runtime Boundary
|
|
55
|
+
|
|
56
|
+
V1 primary mode is personal local mode.
|
|
57
|
+
|
|
58
|
+
Required behavior:
|
|
59
|
+
|
|
60
|
+
- The bridge runs on the owner's workstation or personal development host.
|
|
61
|
+
- Codex edits the selected local workspace directly under the configured sandbox.
|
|
62
|
+
- Owner-only usage is the safest default, while allowed users/groups are opt-in.
|
|
63
|
+
- Team-managed worktrees, containers, PR automation, and remote multi-tenant hosting are future modes.
|
|
64
|
+
- App-server execution is not required for V1, but the runner interface must not block adding it later.
|
|
65
|
+
|
|
66
|
+
### 3.1 Profile Create
|
|
67
|
+
|
|
68
|
+
Command:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
feishu-codex profile create <name>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Required behavior:
|
|
75
|
+
|
|
76
|
+
- Prompt for tenant: `feishu` or `lark`.
|
|
77
|
+
- Prompt for app ID and app secret, or run an app-binding wizard if available.
|
|
78
|
+
- Detect Codex SDK/runtime availability.
|
|
79
|
+
- Prompt for Codex auth mode: `api-key`, `codex-home`, or `inherit-user`.
|
|
80
|
+
- For `api-key`, store the API key as a secret reference and validate it with a low-risk availability check.
|
|
81
|
+
- Create a profile-local Codex home unless `inherit-user` is explicitly selected.
|
|
82
|
+
- Initialize profile-local Feishu/Lark CLI identity settings with `bot-only` as the default.
|
|
83
|
+
- Create profile directory under `~/.feishu-codex/profiles/<name>`.
|
|
84
|
+
- Create local state files with secure permissions.
|
|
85
|
+
- Store app secret using configured secret storage.
|
|
86
|
+
- Optionally set an initial workspace.
|
|
87
|
+
|
|
88
|
+
Acceptance criteria:
|
|
89
|
+
|
|
90
|
+
- New profile appears in `profile list`.
|
|
91
|
+
- App secret is not written as cleartext in normal config.
|
|
92
|
+
- Codex API key is not written as cleartext in normal config.
|
|
93
|
+
- `feishu-codex run --profile <name>` can start from the profile.
|
|
94
|
+
|
|
95
|
+
### 3.2 Profile Use/List/Remove/Export
|
|
96
|
+
|
|
97
|
+
Commands:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
feishu-codex profile list
|
|
101
|
+
feishu-codex profile use <name>
|
|
102
|
+
feishu-codex profile remove <name>
|
|
103
|
+
feishu-codex profile export <name>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Required behavior:
|
|
107
|
+
|
|
108
|
+
- `list` shows active profile, tenant, app ID suffix, workspace status, backend, Codex auth mode, and Feishu/Lark CLI identity preset.
|
|
109
|
+
- `use` changes default profile.
|
|
110
|
+
- `remove` archives local state by default.
|
|
111
|
+
- `remove --purge --yes` permanently deletes profile state.
|
|
112
|
+
- `export` redacts secrets unless `--include-secrets --yes` is provided.
|
|
113
|
+
|
|
114
|
+
### 3.3 Foreground Run
|
|
115
|
+
|
|
116
|
+
Command:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
feishu-codex run [--profile <name>] [--workspace <path>]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Required behavior:
|
|
123
|
+
|
|
124
|
+
- Resolve profile.
|
|
125
|
+
- Run preflight checks.
|
|
126
|
+
- Acquire profile and app locks.
|
|
127
|
+
- Connect Feishu/Lark channel.
|
|
128
|
+
- Register process.
|
|
129
|
+
- Listen until signal or `/exit`.
|
|
130
|
+
- Flush stores on shutdown.
|
|
131
|
+
|
|
132
|
+
### 3.4 Background Service
|
|
133
|
+
|
|
134
|
+
Commands:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
feishu-codex start [--profile <name>]
|
|
138
|
+
feishu-codex stop [--profile <name>]
|
|
139
|
+
feishu-codex restart [--profile <name>]
|
|
140
|
+
feishu-codex status [--profile <name>]
|
|
141
|
+
feishu-codex unregister [--profile <name>]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Required behavior:
|
|
145
|
+
|
|
146
|
+
- macOS: launchd user agent.
|
|
147
|
+
- Linux: systemd user service.
|
|
148
|
+
- Windows: Task Scheduler task.
|
|
149
|
+
- Logs written under profile logs directory.
|
|
150
|
+
- Service commands must not depend on temporary `npx` paths.
|
|
151
|
+
|
|
152
|
+
## 4. Feishu/Lark Event Handling
|
|
153
|
+
|
|
154
|
+
### 4.1 Private Message
|
|
155
|
+
|
|
156
|
+
Required behavior:
|
|
157
|
+
|
|
158
|
+
- Accept message when actor is owner, admin, or allowed user.
|
|
159
|
+
- Do not require bot mention.
|
|
160
|
+
- Scope ID is private chat scope.
|
|
161
|
+
- Ordinary messages enter the run queue.
|
|
162
|
+
- Slash commands are handled immediately.
|
|
163
|
+
|
|
164
|
+
Acceptance criteria:
|
|
165
|
+
|
|
166
|
+
- Unauthorized private sender gets no Codex run.
|
|
167
|
+
- Authorized sender receives a streamed response.
|
|
168
|
+
|
|
169
|
+
### 4.2 Group Message
|
|
170
|
+
|
|
171
|
+
Required behavior:
|
|
172
|
+
|
|
173
|
+
- Accept message when group is allowed, or actor is owner/admin.
|
|
174
|
+
- If `requireMentionInGroup` is true, ignore messages without a real bot mention.
|
|
175
|
+
- Ignore mention-all as a trigger.
|
|
176
|
+
- Scope ID is group chat scope.
|
|
177
|
+
|
|
178
|
+
Acceptance criteria:
|
|
179
|
+
|
|
180
|
+
- Allowed group + real mention triggers run.
|
|
181
|
+
- Allowed group + no mention does not trigger run when mention is required.
|
|
182
|
+
- Disallowed group does not run Codex.
|
|
183
|
+
|
|
184
|
+
### 4.3 Topic Group Message
|
|
185
|
+
|
|
186
|
+
Required behavior:
|
|
187
|
+
|
|
188
|
+
- Resolve topic/thread ID.
|
|
189
|
+
- Scope ID includes chat ID and topic/thread ID.
|
|
190
|
+
- Replies are posted back into the same topic when possible.
|
|
191
|
+
- Each topic has independent workspace, queue, active run, and session state.
|
|
192
|
+
|
|
193
|
+
### 4.4 Quoted Message Context
|
|
194
|
+
|
|
195
|
+
Required behavior:
|
|
196
|
+
|
|
197
|
+
- Detect when a message quotes another message.
|
|
198
|
+
- Fetch quoted message content when permitted.
|
|
199
|
+
- Deduplicate quote targets across a batched run.
|
|
200
|
+
- Include quote context in structured prompt.
|
|
201
|
+
- Avoid fetching quote targets that are already part of the current batch.
|
|
202
|
+
|
|
203
|
+
### 4.5 Card Action
|
|
204
|
+
|
|
205
|
+
Required behavior:
|
|
206
|
+
|
|
207
|
+
- Resolve card action scope.
|
|
208
|
+
- Verify actor access before executing.
|
|
209
|
+
- Dispatch built-in command callbacks.
|
|
210
|
+
- Forward signed agent callbacks into the scope queue as synthetic messages.
|
|
211
|
+
- Include CardKit form values when present.
|
|
212
|
+
- Reject unsigned sensitive callbacks.
|
|
213
|
+
|
|
214
|
+
Acceptance criteria:
|
|
215
|
+
|
|
216
|
+
- Stop button stops only the matching active run.
|
|
217
|
+
- Replay of the same callback nonce is rejected.
|
|
218
|
+
- Callback from a different operator is rejected.
|
|
219
|
+
|
|
220
|
+
### 4.6 Document Comment Mention
|
|
221
|
+
|
|
222
|
+
Required behavior:
|
|
223
|
+
|
|
224
|
+
- React only when the bot is mentioned.
|
|
225
|
+
- Support configured document/file types for comment retrieval.
|
|
226
|
+
- Fetch comment text, quote, and context.
|
|
227
|
+
- Build a comment-specific prompt.
|
|
228
|
+
- Run Codex using document-level session continuity.
|
|
229
|
+
- Post plain-text reply into the same comment thread.
|
|
230
|
+
- Skip self-replies.
|
|
231
|
+
|
|
232
|
+
Acceptance criteria:
|
|
233
|
+
|
|
234
|
+
- Mention in supported comment triggers one reply.
|
|
235
|
+
- Reply does not contain raw Markdown formatting unless user explicitly requested literal Markdown.
|
|
236
|
+
- Concurrent comments on the same document do not corrupt the document-level session.
|
|
237
|
+
|
|
238
|
+
## 5. Built-in Commands
|
|
239
|
+
|
|
240
|
+
### 5.1 `/help`
|
|
241
|
+
|
|
242
|
+
Shows available commands and current agent/backend label.
|
|
243
|
+
|
|
244
|
+
### 5.2 `/status`
|
|
245
|
+
|
|
246
|
+
Shows:
|
|
247
|
+
|
|
248
|
+
- profile
|
|
249
|
+
- tenant
|
|
250
|
+
- bot name if known
|
|
251
|
+
- current scope
|
|
252
|
+
- chat mode
|
|
253
|
+
- selected workspace
|
|
254
|
+
- Codex backend
|
|
255
|
+
- Codex auth mode
|
|
256
|
+
- Feishu/Lark CLI identity preset
|
|
257
|
+
- sandbox/access mode
|
|
258
|
+
- current thread ID or empty state
|
|
259
|
+
- active run status
|
|
260
|
+
- queue snapshot
|
|
261
|
+
- access status
|
|
262
|
+
- owner refresh status
|
|
263
|
+
|
|
264
|
+
### 5.3 `/new` and `/reset`
|
|
265
|
+
|
|
266
|
+
Required behavior:
|
|
267
|
+
|
|
268
|
+
- Stop current run if active.
|
|
269
|
+
- Archive or clear active Codex thread for the current scope.
|
|
270
|
+
- Preserve non-session preferences such as idle timeout if configured.
|
|
271
|
+
|
|
272
|
+
### 5.4 `/cd <path>`
|
|
273
|
+
|
|
274
|
+
Required behavior:
|
|
275
|
+
|
|
276
|
+
- Admin-only.
|
|
277
|
+
- Accept absolute paths and `~/...`.
|
|
278
|
+
- Reject relative paths.
|
|
279
|
+
- Resolve realpath.
|
|
280
|
+
- Reject dangerous broad directories.
|
|
281
|
+
- Stop current run.
|
|
282
|
+
- Set current scope workspace.
|
|
283
|
+
- Reset current scope session.
|
|
284
|
+
|
|
285
|
+
### 5.5 `/ws`
|
|
286
|
+
|
|
287
|
+
Subcommands:
|
|
288
|
+
|
|
289
|
+
```text
|
|
290
|
+
/ws list
|
|
291
|
+
/ws save <name>
|
|
292
|
+
/ws add <name> <path>
|
|
293
|
+
/ws use <name>
|
|
294
|
+
/ws remove <name>
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Required behavior:
|
|
298
|
+
|
|
299
|
+
- Admin-only.
|
|
300
|
+
- Workspace aliases are scoped by profile, owner, and chat scope.
|
|
301
|
+
- Legacy global aliases may be read if migration support is enabled.
|
|
302
|
+
- `use` validates the target path before switching.
|
|
303
|
+
- `add` validates the target path before saving.
|
|
304
|
+
|
|
305
|
+
### 5.5.1 `/new group`
|
|
306
|
+
|
|
307
|
+
Required behavior:
|
|
308
|
+
|
|
309
|
+
- Owner/admin-only.
|
|
310
|
+
- Create a new Feishu/Lark group chat.
|
|
311
|
+
- Invite the requesting user.
|
|
312
|
+
- Inherit the source scope workspace when configured.
|
|
313
|
+
- Send a welcome message to the new group.
|
|
314
|
+
- Reply to the source scope with the creation result.
|
|
315
|
+
|
|
316
|
+
### 5.6 `/resume`
|
|
317
|
+
|
|
318
|
+
Required behavior:
|
|
319
|
+
|
|
320
|
+
- Show recent compatible Codex threads for current workspace and policy.
|
|
321
|
+
- In group chats, avoid exposing detailed history unless configured.
|
|
322
|
+
- Issue short-lived nonces for resume candidates.
|
|
323
|
+
- `/resume use <nonce>` restores the selected thread only if scope, cwd, and policy fingerprint match.
|
|
324
|
+
|
|
325
|
+
### 5.7 `/stop`
|
|
326
|
+
|
|
327
|
+
Required behavior:
|
|
328
|
+
|
|
329
|
+
- Stop current scope run.
|
|
330
|
+
- Do not send an extra reply if the run card can update itself.
|
|
331
|
+
- Admins may stop another scope by explicit target.
|
|
332
|
+
|
|
333
|
+
### 5.8 `/timeout`
|
|
334
|
+
|
|
335
|
+
Required behavior:
|
|
336
|
+
|
|
337
|
+
- Show current idle watchdog setting.
|
|
338
|
+
- Set per-scope timeout in minutes.
|
|
339
|
+
- `off` disables per-scope watchdog.
|
|
340
|
+
- `default` clears per-scope override.
|
|
341
|
+
- Clamp allowed values to a safe range.
|
|
342
|
+
|
|
343
|
+
### 5.9 `/config`
|
|
344
|
+
|
|
345
|
+
Required behavior:
|
|
346
|
+
|
|
347
|
+
- Admin-only.
|
|
348
|
+
- Render interactive configuration card.
|
|
349
|
+
- Support reply mode, show tool calls, max concurrency, mention policy, access mode, network access, idle timeout, Codex auth mode, and Feishu/Lark CLI identity preset.
|
|
350
|
+
- Validate form values before saving.
|
|
351
|
+
- Restart or reconnect when changes require it.
|
|
352
|
+
|
|
353
|
+
### 5.10 `/invite` and `/remove`
|
|
354
|
+
|
|
355
|
+
Required behavior:
|
|
356
|
+
|
|
357
|
+
- Admin-only.
|
|
358
|
+
- Add/remove allowed users, groups, and admins.
|
|
359
|
+
- Parse mentioned users from structured mentions.
|
|
360
|
+
- `/invite group` allows current group.
|
|
361
|
+
- `/invite all group` may add all known groups if the platform API permits.
|
|
362
|
+
|
|
363
|
+
### 5.11 `/doctor`
|
|
364
|
+
|
|
365
|
+
Required behavior:
|
|
366
|
+
|
|
367
|
+
- Admin-only.
|
|
368
|
+
- Rate limited per user.
|
|
369
|
+
- Checks workspace, access, policy, queue, Codex availability, and echo run.
|
|
370
|
+
- In group chats, send sensitive diagnostic details privately to the operator.
|
|
371
|
+
|
|
372
|
+
### 5.12 `/ps`, `/exit`, `/reconnect`
|
|
373
|
+
|
|
374
|
+
Required behavior:
|
|
375
|
+
|
|
376
|
+
- Admin-only.
|
|
377
|
+
- `/ps` lists registered connector processes.
|
|
378
|
+
- `/exit <id|#>` stops selected process.
|
|
379
|
+
- `/reconnect` pauses new runs, stops or waits for active runs, reloads config, reconnects channel.
|
|
380
|
+
|
|
381
|
+
## 6. Codex Execution
|
|
382
|
+
|
|
383
|
+
### 6.1 Backend Selection
|
|
384
|
+
|
|
385
|
+
Profile field:
|
|
386
|
+
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"codex": {
|
|
390
|
+
"backend": "sdk"
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Supported values:
|
|
396
|
+
|
|
397
|
+
| Backend | V1 status | Purpose |
|
|
398
|
+
|---|---|---|
|
|
399
|
+
| `sdk` | Required | Normal execution through Codex TypeScript SDK. |
|
|
400
|
+
| `app-server` | Reserved | Advanced lifecycle and approval support in V2. Not used for V1 normal execution. |
|
|
401
|
+
| `exec-json` | Diagnostic fallback | Compatibility fallback for local troubleshooting, not the product default. |
|
|
402
|
+
|
|
403
|
+
### 6.2 Run Input
|
|
404
|
+
|
|
405
|
+
Every Codex run receives:
|
|
406
|
+
|
|
407
|
+
- run ID
|
|
408
|
+
- prompt
|
|
409
|
+
- cwd realpath
|
|
410
|
+
- optional thread ID
|
|
411
|
+
- sandbox mode
|
|
412
|
+
- network access setting
|
|
413
|
+
- image paths
|
|
414
|
+
- profile environment
|
|
415
|
+
- Codex auth material resolved from the profile secret provider
|
|
416
|
+
- Feishu/Lark CLI identity environment when enabled
|
|
417
|
+
- stop signal
|
|
418
|
+
- idle timeout
|
|
419
|
+
|
|
420
|
+
### 6.3 Run Output
|
|
421
|
+
|
|
422
|
+
Runner output must be translated into:
|
|
423
|
+
|
|
424
|
+
- thread started/resumed
|
|
425
|
+
- text delta or final text
|
|
426
|
+
- tool start
|
|
427
|
+
- tool result
|
|
428
|
+
- usage
|
|
429
|
+
- approval request if backend supports it
|
|
430
|
+
- done
|
|
431
|
+
- error
|
|
432
|
+
|
|
433
|
+
### 6.4 Stop Semantics
|
|
434
|
+
|
|
435
|
+
Required behavior:
|
|
436
|
+
|
|
437
|
+
- `/stop` marks the run interrupted.
|
|
438
|
+
- SDK runner uses abort signal first.
|
|
439
|
+
- Process fallback terminates the child process tree when available.
|
|
440
|
+
- Stop has a grace period before force kill.
|
|
441
|
+
- Card terminal state becomes interrupted.
|
|
442
|
+
|
|
443
|
+
### 6.5 Thread Continuity
|
|
444
|
+
|
|
445
|
+
Required behavior:
|
|
446
|
+
|
|
447
|
+
- Save Codex thread ID after first successful thread event.
|
|
448
|
+
- Resume only when scope, cwd, and policy fingerprint match.
|
|
449
|
+
- Reset thread on `/new`, `/cd`, or incompatible policy change.
|
|
450
|
+
|
|
451
|
+
### 6.6 Codex Authentication
|
|
452
|
+
|
|
453
|
+
Profile field:
|
|
454
|
+
|
|
455
|
+
```json
|
|
456
|
+
{
|
|
457
|
+
"codex": {
|
|
458
|
+
"backend": "sdk",
|
|
459
|
+
"auth": {
|
|
460
|
+
"mode": "api-key",
|
|
461
|
+
"apiKey": { "source": "keystore", "id": "openai-api-key-default" }
|
|
462
|
+
},
|
|
463
|
+
"codexHome": "~/.feishu-codex/profiles/default/codex-home",
|
|
464
|
+
"inheritUserCodexHome": false
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
Supported auth modes:
|
|
470
|
+
|
|
471
|
+
| Mode | V1 status | Required behavior |
|
|
472
|
+
|---|---|---|
|
|
473
|
+
| `api-key` | Required | Resolve a profile secret and pass it to the Codex SDK for the run. |
|
|
474
|
+
| `codex-home` | Required | Use a profile-local Codex home containing local Codex login/config state. |
|
|
475
|
+
| `inherit-user` | Optional | Reuse the host user's Codex login only after explicit owner configuration. |
|
|
476
|
+
|
|
477
|
+
Acceptance criteria:
|
|
478
|
+
|
|
479
|
+
- API key mode can run Codex from a background service without an interactive Codex login.
|
|
480
|
+
- API keys are never shown in `/status`, `/doctor`, logs, card payloads, or exported config unless `--include-secrets --yes` is explicitly used.
|
|
481
|
+
- API key injection is scoped to the Codex SDK child execution and is not added to the connector process-wide environment.
|
|
482
|
+
- Changing auth mode invalidates incompatible session fingerprints.
|
|
483
|
+
|
|
484
|
+
### 6.7 Codex API Key Remote Operation
|
|
485
|
+
|
|
486
|
+
Codex API key mode supports Feishu remote operation because the Feishu/Lark user does not need to be physically present at the host to complete an auth prompt.
|
|
487
|
+
|
|
488
|
+
Required behavior:
|
|
489
|
+
|
|
490
|
+
- The bridge owner configures the key locally through `profile create`, `profile set codex.api-key`, or an equivalent secret command.
|
|
491
|
+
- The bridge stores only a secret reference in normal config.
|
|
492
|
+
- The SDK runner passes the key through the SDK option or a run-scoped child environment.
|
|
493
|
+
- The prompt must tell Codex not to reveal or inspect bridge secret files.
|
|
494
|
+
- If API key resolution fails, the run rejects before Codex starts and the user receives a non-sensitive diagnostic.
|
|
495
|
+
|
|
496
|
+
Security constraints:
|
|
497
|
+
|
|
498
|
+
- Default sandbox remains `workspace-write` at most.
|
|
499
|
+
- `danger-full-access` is controlled by the same profile permission policy for every Codex auth mode.
|
|
500
|
+
- Shell/tool output is scanned for accidental key echoes before rendering when feasible.
|
|
501
|
+
|
|
502
|
+
### 6.8 Feishu/Lark CLI Identity Projection
|
|
503
|
+
|
|
504
|
+
Profile field:
|
|
505
|
+
|
|
506
|
+
```json
|
|
507
|
+
{
|
|
508
|
+
"feishuCli": {
|
|
509
|
+
"enabled": true,
|
|
510
|
+
"identityPreset": "bot-only",
|
|
511
|
+
"configDir": "~/.feishu-codex/profiles/default/feishu-cli"
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
Supported identity presets:
|
|
517
|
+
|
|
518
|
+
| Preset | V1 status | Required behavior |
|
|
519
|
+
|---|---|---|
|
|
520
|
+
| `bot-only` | Required default | Prepare CLI config/env for the Feishu/Lark app bot identity. |
|
|
521
|
+
| `user-default` | Required for personal mode | Use the local user's CLI OAuth identity only when explicitly configured. |
|
|
522
|
+
| `disabled` | Required | Do not expose Feishu/Lark CLI credentials or config to Codex. |
|
|
523
|
+
|
|
524
|
+
Required behavior:
|
|
525
|
+
|
|
526
|
+
- Inject CLI config directory and identity env only into Codex runs.
|
|
527
|
+
- Keep profile CLI config separate from host-global CLI config.
|
|
528
|
+
- Show identity preset and health in `/status` and `/doctor`.
|
|
529
|
+
- Deny `user-default` in group chats unless the owner explicitly allows it.
|
|
530
|
+
- Add identity preset and config digest into the policy fingerprint.
|
|
531
|
+
|
|
532
|
+
Acceptance criteria:
|
|
533
|
+
|
|
534
|
+
- In `bot-only` mode, Codex can call configured Feishu/Lark CLI operations as the bot/app.
|
|
535
|
+
- In `user-default` mode, Codex can use the local user's CLI identity for personal chats after explicit setup.
|
|
536
|
+
- In `disabled` mode, Codex receives no Feishu/Lark CLI credential environment.
|
|
537
|
+
- Token values never appear in rendered replies, logs, or diagnostics.
|
|
538
|
+
|
|
539
|
+
## 7. Queueing and Concurrency
|
|
540
|
+
|
|
541
|
+
### 7.1 Debounce
|
|
542
|
+
|
|
543
|
+
Required behavior:
|
|
544
|
+
|
|
545
|
+
- Default quiet window: 600 ms.
|
|
546
|
+
- Multiple messages in the same scope are batched into one prompt.
|
|
547
|
+
- Sender annotations are included when a batch has multiple messages.
|
|
548
|
+
|
|
549
|
+
### 7.2 Active Run Rule
|
|
550
|
+
|
|
551
|
+
Required behavior:
|
|
552
|
+
|
|
553
|
+
- At most one active Codex run per scope.
|
|
554
|
+
- Messages received during an active run are queued for the next run.
|
|
555
|
+
- Commands bypass pending queue.
|
|
556
|
+
|
|
557
|
+
### 7.3 Global Pool
|
|
558
|
+
|
|
559
|
+
Required behavior:
|
|
560
|
+
|
|
561
|
+
- Configurable max concurrent runs.
|
|
562
|
+
- Excess runs wait FIFO.
|
|
563
|
+
- `/doctor` may use non-waiting acquire and report pool full.
|
|
564
|
+
|
|
565
|
+
## 8. Rendering
|
|
566
|
+
|
|
567
|
+
### 8.1 Reply Modes
|
|
568
|
+
|
|
569
|
+
Supported modes:
|
|
570
|
+
|
|
571
|
+
- `card`
|
|
572
|
+
- `markdown`
|
|
573
|
+
- `text`
|
|
574
|
+
|
|
575
|
+
Default:
|
|
576
|
+
|
|
577
|
+
```text
|
|
578
|
+
card for V1, markdown/text only as fallback
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### 8.2 Run Card
|
|
582
|
+
|
|
583
|
+
Card must show:
|
|
584
|
+
|
|
585
|
+
- status header
|
|
586
|
+
- text output
|
|
587
|
+
- tool calls if enabled
|
|
588
|
+
- terminal status
|
|
589
|
+
- stop button while running
|
|
590
|
+
- optional usage footer
|
|
591
|
+
- run ID or short run reference
|
|
592
|
+
- selected workspace suffix
|
|
593
|
+
- sandbox/access mode
|
|
594
|
+
- Codex auth mode label without secret details
|
|
595
|
+
|
|
596
|
+
### 8.3 Stream Fallback
|
|
597
|
+
|
|
598
|
+
Required behavior:
|
|
599
|
+
|
|
600
|
+
- If streaming card creation fails, send one final markdown reply.
|
|
601
|
+
- If final markdown fails due to platform audit, send a neutral safe fallback.
|
|
602
|
+
|
|
603
|
+
## 9. Attachment Handling
|
|
604
|
+
|
|
605
|
+
### 9.1 Supported Inputs
|
|
606
|
+
|
|
607
|
+
| Resource | V1 behavior |
|
|
608
|
+
|---|---|
|
|
609
|
+
| Image | Download, cache, pass to Codex if policy accepts. |
|
|
610
|
+
| File | Download and include path/context if policy accepts; not necessarily passed natively. |
|
|
611
|
+
| Audio | Skip unless later transcribed. |
|
|
612
|
+
| Video | Skip unless later supported. |
|
|
613
|
+
| Sticker | Skip. |
|
|
614
|
+
|
|
615
|
+
### 9.2 Policy
|
|
616
|
+
|
|
617
|
+
Default limits:
|
|
618
|
+
|
|
619
|
+
- max attachment count: 10
|
|
620
|
+
- max per file: 25 MB
|
|
621
|
+
- max per image: 25 MB
|
|
622
|
+
- max total per run: 100 MB
|
|
623
|
+
- cache TTL: 24 hours
|
|
624
|
+
|
|
625
|
+
Rejected required attachments reject the run. Optional rejected attachments are shown in prompt context as rejected.
|
|
626
|
+
|
|
627
|
+
## 10. Access Control
|
|
628
|
+
|
|
629
|
+
### 10.1 Defaults
|
|
630
|
+
|
|
631
|
+
- Owner can always use and administer the bot.
|
|
632
|
+
- Admin list is empty by default.
|
|
633
|
+
- Allowed users list is empty by default.
|
|
634
|
+
- Allowed groups list is empty by default.
|
|
635
|
+
- Unknown users are denied.
|
|
636
|
+
- Group messages require bot mention by default.
|
|
637
|
+
|
|
638
|
+
### 10.2 Owner Resolution
|
|
639
|
+
|
|
640
|
+
Required behavior:
|
|
641
|
+
|
|
642
|
+
- Refresh owner identity from platform APIs when possible.
|
|
643
|
+
- Cache owner ID in runtime controls.
|
|
644
|
+
- If refresh fails, do not widen access.
|
|
645
|
+
|
|
646
|
+
### 10.3 Denial Behavior
|
|
647
|
+
|
|
648
|
+
Required behavior:
|
|
649
|
+
|
|
650
|
+
- Private unauthorized messages are silently ignored.
|
|
651
|
+
- Group unauthorized messages are usually ignored.
|
|
652
|
+
- If a disallowed group mentions the bot, a short admin instruction may be sent if policy allows.
|
|
653
|
+
|
|
654
|
+
## 11. Workspace Safety
|
|
655
|
+
|
|
656
|
+
Reject:
|
|
657
|
+
|
|
658
|
+
- empty cwd
|
|
659
|
+
- inaccessible path
|
|
660
|
+
- non-directory path
|
|
661
|
+
- filesystem root
|
|
662
|
+
- home root
|
|
663
|
+
- user root
|
|
664
|
+
- broad user folders such as Desktop or Downloads
|
|
665
|
+
- system roots
|
|
666
|
+
- temp root
|
|
667
|
+
- volume root
|
|
668
|
+
|
|
669
|
+
Acceptance criteria:
|
|
670
|
+
|
|
671
|
+
- Missing cwd rejects the run instead of falling back to home.
|
|
672
|
+
- Workspace changes clear current thread state.
|
|
673
|
+
- Workspace aliases cannot bypass realpath validation.
|
|
674
|
+
|
|
675
|
+
## 12. Secrets and Local State
|
|
676
|
+
|
|
677
|
+
### 12.1 State Directory
|
|
678
|
+
|
|
679
|
+
Default:
|
|
680
|
+
|
|
681
|
+
```text
|
|
682
|
+
~/.feishu-codex
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
Profile files:
|
|
686
|
+
|
|
687
|
+
```text
|
|
688
|
+
profiles/<profile>/config.json
|
|
689
|
+
profiles/<profile>/sessions.json
|
|
690
|
+
profiles/<profile>/session-catalog.json
|
|
691
|
+
profiles/<profile>/workspaces.json
|
|
692
|
+
profiles/<profile>/media/
|
|
693
|
+
profiles/<profile>/logs/
|
|
694
|
+
profiles/<profile>/secrets.enc
|
|
695
|
+
profiles/<profile>/codex-home/
|
|
696
|
+
profiles/<profile>/feishu-cli/
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### 12.2 Secret Providers
|
|
700
|
+
|
|
701
|
+
Supported:
|
|
702
|
+
|
|
703
|
+
- encrypted local keystore
|
|
704
|
+
- environment variable
|
|
705
|
+
- file
|
|
706
|
+
- exec provider
|
|
707
|
+
|
|
708
|
+
Secrets must never be logged or shown in `/status`.
|
|
709
|
+
|
|
710
|
+
## 13. Diagnostics and Observability
|
|
711
|
+
|
|
712
|
+
### 13.1 Logs
|
|
713
|
+
|
|
714
|
+
Structured logs must include:
|
|
715
|
+
|
|
716
|
+
- profile
|
|
717
|
+
- scope
|
|
718
|
+
- run ID
|
|
719
|
+
- source
|
|
720
|
+
- event phase
|
|
721
|
+
- result
|
|
722
|
+
- timing
|
|
723
|
+
- sanitized error
|
|
724
|
+
|
|
725
|
+
### 13.2 Doctor Report
|
|
726
|
+
|
|
727
|
+
Report:
|
|
728
|
+
|
|
729
|
+
- self-check
|
|
730
|
+
- profile
|
|
731
|
+
- backend
|
|
732
|
+
- workspace
|
|
733
|
+
- sandbox
|
|
734
|
+
- access
|
|
735
|
+
- owner status
|
|
736
|
+
- queue snapshot
|
|
737
|
+
- Codex availability
|
|
738
|
+
- echo result
|
|
739
|
+
|
|
740
|
+
### 13.3 Optional Telemetry
|
|
741
|
+
|
|
742
|
+
Telemetry is disabled by default. If enabled, it must be adapter-based and must not block bridge operation.
|
|
743
|
+
|
|
744
|
+
## 14. Approval Mapping
|
|
745
|
+
|
|
746
|
+
V1 does not implement Codex runtime approval mapping. It uses explicit sandbox policy and non-interactive Codex execution. The app-server architecture and data model are reserved for V2:
|
|
747
|
+
|
|
748
|
+
```ts
|
|
749
|
+
interface ApprovalRequest {
|
|
750
|
+
id: string;
|
|
751
|
+
runId: string;
|
|
752
|
+
scopeId: string;
|
|
753
|
+
cwd: string;
|
|
754
|
+
sandbox: string;
|
|
755
|
+
action: string;
|
|
756
|
+
command?: string;
|
|
757
|
+
riskSummary?: string;
|
|
758
|
+
}
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
V2 acceptance criteria:
|
|
762
|
+
|
|
763
|
+
- App-server runner receives approval request.
|
|
764
|
+
- Bridge sends signed approval card.
|
|
765
|
+
- Only authorized actor/admin can approve.
|
|
766
|
+
- Approval and denial are sent back to Codex.
|
|
767
|
+
- Decision is logged with sanitized action metadata.
|
|
768
|
+
|
|
769
|
+
## 15. Non-functional Requirements
|
|
770
|
+
|
|
771
|
+
### 15.1 Reliability
|
|
772
|
+
|
|
773
|
+
- Reconnect channel after network interruption.
|
|
774
|
+
- Flush local stores on shutdown.
|
|
775
|
+
- Protect local state with atomic writes.
|
|
776
|
+
- Prevent duplicate runtime per profile/app.
|
|
777
|
+
|
|
778
|
+
### 15.2 Security
|
|
779
|
+
|
|
780
|
+
- Default no full access.
|
|
781
|
+
- Default no command network access.
|
|
782
|
+
- No plaintext app secret in config.
|
|
783
|
+
- No plaintext Codex API key in config.
|
|
784
|
+
- API key and Feishu/Lark CLI credential material are injected only into run-scoped Codex execution.
|
|
785
|
+
- Signed card callbacks.
|
|
786
|
+
- Policy-bound session resume.
|
|
787
|
+
- Workspace validation.
|
|
788
|
+
- Least-privilege group access.
|
|
789
|
+
- `user-default` Feishu/Lark CLI identity is disabled for group chats unless explicitly allowed.
|
|
790
|
+
|
|
791
|
+
### 15.3 Portability
|
|
792
|
+
|
|
793
|
+
- macOS, Linux, Windows support.
|
|
794
|
+
- Node.js 20+ target.
|
|
795
|
+
- Paths normalized by platform.
|
|
796
|
+
|
|
797
|
+
### 15.4 Maintainability
|
|
798
|
+
|
|
799
|
+
- Runner interface isolates Codex backend changes.
|
|
800
|
+
- Feishu/Lark gateway isolates platform SDK changes.
|
|
801
|
+
- Policy module owns access and sandbox decisions.
|
|
802
|
+
- Renderer module owns card schema.
|
|
803
|
+
|
|
804
|
+
## 16. V1 Acceptance Checklist
|
|
805
|
+
|
|
806
|
+
- Private owner can run a Codex task.
|
|
807
|
+
- Allowed group can run a Codex task only when mention policy is satisfied.
|
|
808
|
+
- Unauthorized user cannot trigger a run.
|
|
809
|
+
- `/cd` switches workspace and resets session.
|
|
810
|
+
- Invalid workspace rejects before Codex starts.
|
|
811
|
+
- `/stop` interrupts an active run.
|
|
812
|
+
- Messages during active run queue into next run.
|
|
813
|
+
- Thread resumes only when cwd and policy match.
|
|
814
|
+
- Images are downloaded and passed to Codex when accepted.
|
|
815
|
+
- Run output streams back through a rich Feishu/Lark card.
|
|
816
|
+
- Card stop callback is signed and replay-protected.
|
|
817
|
+
- Markdown/text fallback works when card rendering fails.
|
|
818
|
+
- Codex API key auth can run without interactive Codex login.
|
|
819
|
+
- Codex API key is not logged, rendered, or exported by default.
|
|
820
|
+
- Codex receives the configured profile-local Feishu/Lark CLI identity env.
|
|
821
|
+
- `disabled` CLI identity mode exposes no Feishu/Lark CLI credential environment to Codex.
|
|
822
|
+
- `/status` shows runtime state.
|
|
823
|
+
- `/doctor` performs a low-sensitive echo run.
|
|
824
|
+
- Foreground and daemon modes work.
|
|
825
|
+
- Logs contain no secrets.
|