codeksei 0.1.0 → 0.1.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/LICENSE +661 -661
- package/README.en.md +109 -47
- package/README.md +79 -58
- package/bin/cyberboss.js +1 -1
- package/package.json +86 -86
- package/scripts/open_shared_wechat_thread.sh +77 -77
- package/scripts/open_wechat_thread.sh +108 -108
- package/scripts/shared-common.js +144 -144
- package/scripts/shared-open.js +14 -14
- package/scripts/shared-start.js +5 -5
- package/scripts/shared-status.js +27 -27
- package/scripts/show_shared_status.sh +45 -45
- package/scripts/start_shared_app_server.sh +52 -52
- package/scripts/start_shared_wechat.sh +94 -94
- package/scripts/timeline-screenshot.sh +14 -14
- package/src/adapters/channel/weixin/account-store.js +99 -99
- package/src/adapters/channel/weixin/api-v2.js +50 -50
- package/src/adapters/channel/weixin/api.js +169 -169
- package/src/adapters/channel/weixin/context-token-store.js +84 -84
- package/src/adapters/channel/weixin/index.js +618 -604
- package/src/adapters/channel/weixin/legacy.js +579 -566
- package/src/adapters/channel/weixin/media-mime.js +22 -22
- package/src/adapters/channel/weixin/media-receive.js +370 -370
- package/src/adapters/channel/weixin/media-send.js +102 -102
- package/src/adapters/channel/weixin/message-utils-v2.js +282 -282
- package/src/adapters/channel/weixin/message-utils.js +199 -199
- package/src/adapters/channel/weixin/redact.js +41 -41
- package/src/adapters/channel/weixin/reminder-queue-store.js +101 -101
- package/src/adapters/channel/weixin/sync-buffer-store.js +35 -35
- package/src/adapters/runtime/codex/events.js +215 -215
- package/src/adapters/runtime/codex/index.js +109 -104
- package/src/adapters/runtime/codex/message-utils.js +95 -95
- package/src/adapters/runtime/codex/model-catalog.js +106 -106
- package/src/adapters/runtime/codex/protocol-leak-monitor.js +75 -75
- package/src/adapters/runtime/codex/rpc-client.js +339 -339
- package/src/adapters/runtime/codex/session-store.js +286 -286
- package/src/app/channel-send-file-cli.js +57 -57
- package/src/app/diary-write-cli.js +236 -88
- package/src/app/note-sync-cli.js +2 -2
- package/src/app/reminder-write-cli.js +215 -210
- package/src/app/review-cli.js +7 -5
- package/src/app/system-checkin-poller.js +64 -64
- package/src/app/system-send-cli.js +129 -129
- package/src/app/timeline-event-cli.js +28 -25
- package/src/app/timeline-screenshot-cli.js +103 -100
- package/src/core/app.js +1763 -1763
- package/src/core/branding.js +2 -1
- package/src/core/command-registry.js +381 -369
- package/src/core/config.js +30 -14
- package/src/core/default-targets.js +163 -163
- package/src/core/durable-note-schema.js +9 -8
- package/src/core/instructions-template.js +17 -16
- package/src/core/note-sync.js +8 -7
- package/src/core/path-utils.js +54 -0
- package/src/core/project-radar.js +11 -10
- package/src/core/review.js +48 -50
- package/src/core/stream-delivery.js +1162 -983
- package/src/core/system-message-dispatcher.js +68 -68
- package/src/core/system-message-queue-store.js +128 -128
- package/src/core/thread-state-store.js +96 -96
- package/src/core/timeline-screenshot-queue-store.js +134 -134
- package/src/core/timezone.js +436 -0
- package/src/core/workspace-bootstrap.js +9 -1
- package/src/index.js +148 -146
- package/src/integrations/timeline/index.js +130 -74
- package/src/integrations/timeline/state-sync.js +240 -0
- package/templates/weixin-instructions.md +12 -38
- package/templates/weixin-operations.md +29 -31
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
const COMMAND_GROUPS = [
|
|
2
|
-
{
|
|
3
|
-
id: "lifecycle",
|
|
4
|
-
label: "启动与诊断",
|
|
5
|
-
actions: [
|
|
6
|
-
{
|
|
7
|
-
action: "app.login",
|
|
8
|
-
summary: "发起微信扫码登录并保存账号",
|
|
9
|
-
terminal: ["login"],
|
|
10
|
-
weixin: [],
|
|
11
|
-
status: "active",
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
action: "app.accounts",
|
|
15
|
-
summary: "查看本地已保存账号",
|
|
16
|
-
terminal: ["accounts"],
|
|
17
|
-
weixin: [],
|
|
18
|
-
status: "active",
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
action: "app.start",
|
|
22
|
-
summary: "启动当前 channel/runtime 主循环",
|
|
23
|
-
terminal: ["start"],
|
|
24
|
-
weixin: [],
|
|
25
|
-
status: "active",
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
action: "app.shared_start",
|
|
29
|
-
summary: "启动共享 app-server 与共享微信桥接",
|
|
30
|
-
terminal: ["shared start"],
|
|
31
|
-
weixin: [],
|
|
32
|
-
status: "active",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
action: "app.shared_open",
|
|
36
|
-
summary: "接入当前微信绑定的共享线程",
|
|
37
|
-
terminal: ["shared open"],
|
|
38
|
-
weixin: [],
|
|
39
|
-
status: "active",
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
action: "app.shared_status",
|
|
43
|
-
summary: "查看共享 app-server 与共享桥接状态",
|
|
44
|
-
terminal: ["shared status"],
|
|
45
|
-
weixin: [],
|
|
46
|
-
status: "active",
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
action: "app.doctor",
|
|
50
|
-
summary: "打印当前配置、边界和线程状态",
|
|
51
|
-
terminal: ["doctor"],
|
|
52
|
-
weixin: [],
|
|
53
|
-
status: "active",
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
action: "system.send",
|
|
57
|
-
summary: "向内部系统队列写入一条不可见触发消息",
|
|
58
|
-
terminal: ["system send"],
|
|
59
|
-
terminalGroup: "system",
|
|
60
|
-
weixin: [],
|
|
61
|
-
status: "active",
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
action: "system.checkin_poller",
|
|
65
|
-
summary: "按随机间隔写入主动 check-in 触发",
|
|
66
|
-
terminal: ["system checkin-poller"],
|
|
67
|
-
terminalGroup: "system",
|
|
68
|
-
weixin: [],
|
|
69
|
-
status: "active",
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
id: "workspace",
|
|
75
|
-
label: "项目与线程",
|
|
76
|
-
actions: [
|
|
77
|
-
{
|
|
78
|
-
action: "workspace.bind",
|
|
79
|
-
summary: "绑定当前聊天使用的项目目录",
|
|
80
|
-
terminal: [],
|
|
81
|
-
weixin: ["/bind"],
|
|
82
|
-
status: "active",
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
action: "workspace.status",
|
|
86
|
-
summary: "查看当前项目、线程、模型与上下文使用情况",
|
|
87
|
-
terminal: [],
|
|
88
|
-
weixin: ["/status"],
|
|
89
|
-
status: "active",
|
|
90
|
-
},
|
|
1
|
+
const COMMAND_GROUPS = [
|
|
2
|
+
{
|
|
3
|
+
id: "lifecycle",
|
|
4
|
+
label: "启动与诊断",
|
|
5
|
+
actions: [
|
|
6
|
+
{
|
|
7
|
+
action: "app.login",
|
|
8
|
+
summary: "发起微信扫码登录并保存账号",
|
|
9
|
+
terminal: ["login"],
|
|
10
|
+
weixin: [],
|
|
11
|
+
status: "active",
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
action: "app.accounts",
|
|
15
|
+
summary: "查看本地已保存账号",
|
|
16
|
+
terminal: ["accounts"],
|
|
17
|
+
weixin: [],
|
|
18
|
+
status: "active",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
action: "app.start",
|
|
22
|
+
summary: "启动当前 channel/runtime 主循环",
|
|
23
|
+
terminal: ["start"],
|
|
24
|
+
weixin: [],
|
|
25
|
+
status: "active",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
action: "app.shared_start",
|
|
29
|
+
summary: "启动共享 app-server 与共享微信桥接",
|
|
30
|
+
terminal: ["shared start"],
|
|
31
|
+
weixin: [],
|
|
32
|
+
status: "active",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
action: "app.shared_open",
|
|
36
|
+
summary: "接入当前微信绑定的共享线程",
|
|
37
|
+
terminal: ["shared open"],
|
|
38
|
+
weixin: [],
|
|
39
|
+
status: "active",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
action: "app.shared_status",
|
|
43
|
+
summary: "查看共享 app-server 与共享桥接状态",
|
|
44
|
+
terminal: ["shared status"],
|
|
45
|
+
weixin: [],
|
|
46
|
+
status: "active",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
action: "app.doctor",
|
|
50
|
+
summary: "打印当前配置、边界和线程状态",
|
|
51
|
+
terminal: ["doctor"],
|
|
52
|
+
weixin: [],
|
|
53
|
+
status: "active",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
action: "system.send",
|
|
57
|
+
summary: "向内部系统队列写入一条不可见触发消息",
|
|
58
|
+
terminal: ["system send"],
|
|
59
|
+
terminalGroup: "system",
|
|
60
|
+
weixin: [],
|
|
61
|
+
status: "active",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
action: "system.checkin_poller",
|
|
65
|
+
summary: "按随机间隔写入主动 check-in 触发",
|
|
66
|
+
terminal: ["system checkin-poller"],
|
|
67
|
+
terminalGroup: "system",
|
|
68
|
+
weixin: [],
|
|
69
|
+
status: "active",
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "workspace",
|
|
75
|
+
label: "项目与线程",
|
|
76
|
+
actions: [
|
|
77
|
+
{
|
|
78
|
+
action: "workspace.bind",
|
|
79
|
+
summary: "绑定当前聊天使用的项目目录",
|
|
80
|
+
terminal: [],
|
|
81
|
+
weixin: ["/bind"],
|
|
82
|
+
status: "active",
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
action: "workspace.status",
|
|
86
|
+
summary: "查看当前项目、线程、模型与上下文使用情况",
|
|
87
|
+
terminal: [],
|
|
88
|
+
weixin: ["/status"],
|
|
89
|
+
status: "active",
|
|
90
|
+
},
|
|
91
91
|
{
|
|
92
92
|
action: "thread.new",
|
|
93
93
|
summary: "切到新线程草稿,并在下一条消息前重建当前 workspace 上下文",
|
|
@@ -109,39 +109,39 @@ const COMMAND_GROUPS = [
|
|
|
109
109
|
weixin: ["/switch <threadId>"],
|
|
110
110
|
status: "active",
|
|
111
111
|
},
|
|
112
|
-
{
|
|
113
|
-
action: "thread.stop",
|
|
114
|
-
summary: "停止当前线程中的运行",
|
|
115
|
-
terminal: [],
|
|
116
|
-
weixin: ["/stop"],
|
|
117
|
-
status: "active",
|
|
118
|
-
},
|
|
119
|
-
],
|
|
120
|
-
},
|
|
112
|
+
{
|
|
113
|
+
action: "thread.stop",
|
|
114
|
+
summary: "停止当前线程中的运行",
|
|
115
|
+
terminal: [],
|
|
116
|
+
weixin: ["/stop"],
|
|
117
|
+
status: "active",
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
121
|
{
|
|
122
122
|
id: "approval",
|
|
123
123
|
label: "授权与控制",
|
|
124
|
-
actions: [
|
|
125
|
-
{
|
|
126
|
-
action: "approval.accept_once",
|
|
127
|
-
summary: "允许当前待处理的授权请求一次",
|
|
128
|
-
terminal: [],
|
|
129
|
-
weixin: ["/yes"],
|
|
130
|
-
status: "active",
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
action: "approval.accept_workspace",
|
|
134
|
-
summary: "在当前项目内持续允许同前缀命令",
|
|
135
|
-
terminal: [],
|
|
136
|
-
weixin: ["/always"],
|
|
137
|
-
status: "active",
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
action: "approval.reject_once",
|
|
141
|
-
summary: "拒绝当前待处理的授权请求",
|
|
142
|
-
terminal: [],
|
|
143
|
-
weixin: ["/no"],
|
|
144
|
-
status: "active",
|
|
124
|
+
actions: [
|
|
125
|
+
{
|
|
126
|
+
action: "approval.accept_once",
|
|
127
|
+
summary: "允许当前待处理的授权请求一次",
|
|
128
|
+
terminal: [],
|
|
129
|
+
weixin: ["/yes"],
|
|
130
|
+
status: "active",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
action: "approval.accept_workspace",
|
|
134
|
+
summary: "在当前项目内持续允许同前缀命令",
|
|
135
|
+
terminal: [],
|
|
136
|
+
weixin: ["/always"],
|
|
137
|
+
status: "active",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
action: "approval.reject_once",
|
|
141
|
+
summary: "拒绝当前待处理的授权请求",
|
|
142
|
+
terminal: [],
|
|
143
|
+
weixin: ["/no"],
|
|
144
|
+
status: "active",
|
|
145
145
|
},
|
|
146
146
|
],
|
|
147
147
|
},
|
|
@@ -210,29 +210,29 @@ const COMMAND_GROUPS = [
|
|
|
210
210
|
{
|
|
211
211
|
id: "capabilities",
|
|
212
212
|
label: "能力集成",
|
|
213
|
-
actions: [
|
|
214
|
-
{
|
|
215
|
-
action: "model.inspect",
|
|
216
|
-
summary: "查看当前模型",
|
|
217
|
-
terminal: [],
|
|
218
|
-
weixin: ["/model"],
|
|
219
|
-
status: "active",
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
action: "model.select",
|
|
223
|
-
summary: "切换到指定模型",
|
|
224
|
-
terminal: [],
|
|
225
|
-
weixin: ["/model <id>"],
|
|
226
|
-
status: "active",
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
action: "channel.send_file",
|
|
230
|
-
summary: "将文件作为附件发送回当前聊天",
|
|
231
|
-
terminal: ["channel send-file"],
|
|
232
|
-
terminalGroup: "channel",
|
|
233
|
-
weixin: [],
|
|
234
|
-
status: "active",
|
|
235
|
-
},
|
|
213
|
+
actions: [
|
|
214
|
+
{
|
|
215
|
+
action: "model.inspect",
|
|
216
|
+
summary: "查看当前模型",
|
|
217
|
+
terminal: [],
|
|
218
|
+
weixin: ["/model"],
|
|
219
|
+
status: "active",
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
action: "model.select",
|
|
223
|
+
summary: "切换到指定模型",
|
|
224
|
+
terminal: [],
|
|
225
|
+
weixin: ["/model <id>"],
|
|
226
|
+
status: "active",
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
action: "channel.send_file",
|
|
230
|
+
summary: "将文件作为附件发送回当前聊天",
|
|
231
|
+
terminal: ["channel send-file"],
|
|
232
|
+
terminalGroup: "channel",
|
|
233
|
+
weixin: [],
|
|
234
|
+
status: "active",
|
|
235
|
+
},
|
|
236
236
|
{
|
|
237
237
|
action: "timeline.event",
|
|
238
238
|
summary: "按单个时间块写入时间轴,不必手写 JSON",
|
|
@@ -243,7 +243,7 @@ const COMMAND_GROUPS = [
|
|
|
243
243
|
},
|
|
244
244
|
{
|
|
245
245
|
action: "timeline.write",
|
|
246
|
-
summary: "
|
|
246
|
+
summary: "按批量或原始 JSON 写入时间轴事件(低层入口)",
|
|
247
247
|
terminal: ["timeline write"],
|
|
248
248
|
terminalGroup: "timeline",
|
|
249
249
|
weixin: [],
|
|
@@ -278,68 +278,68 @@ const COMMAND_GROUPS = [
|
|
|
278
278
|
summary: "构建时间轴静态页面",
|
|
279
279
|
terminal: ["timeline build"],
|
|
280
280
|
terminalGroup: "timeline",
|
|
281
|
-
weixin: [],
|
|
282
|
-
status: "active",
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
action: "timeline.serve",
|
|
286
|
-
summary: "启动时间轴静态页面服务",
|
|
287
|
-
terminal: ["timeline serve"],
|
|
288
|
-
terminalGroup: "timeline",
|
|
289
|
-
weixin: [],
|
|
290
|
-
status: "active",
|
|
291
|
-
},
|
|
292
|
-
{
|
|
293
|
-
action: "timeline.dev",
|
|
294
|
-
summary: "启动时间轴热更新开发服务",
|
|
295
|
-
terminal: ["timeline dev"],
|
|
296
|
-
terminalGroup: "timeline",
|
|
297
|
-
weixin: [],
|
|
298
|
-
status: "active",
|
|
299
|
-
},
|
|
300
|
-
{
|
|
301
|
-
action: "timeline.screenshot",
|
|
302
|
-
summary: "截图时间轴页面",
|
|
303
|
-
terminal: ["timeline screenshot"],
|
|
304
|
-
terminalGroup: "timeline",
|
|
305
|
-
weixin: [],
|
|
306
|
-
status: "active",
|
|
307
|
-
},
|
|
308
|
-
{
|
|
309
|
-
action: "reminder.create",
|
|
310
|
-
summary: "创建提醒并交给调度层处理",
|
|
311
|
-
terminal: ["reminder write"],
|
|
312
|
-
terminalGroup: "reminder",
|
|
313
|
-
weixin: [],
|
|
314
|
-
status: "active",
|
|
315
|
-
},
|
|
316
|
-
{
|
|
317
|
-
action: "diary.append",
|
|
318
|
-
summary: "追加一条日记记录",
|
|
319
|
-
terminal: ["diary write"],
|
|
320
|
-
terminalGroup: "diary",
|
|
321
|
-
weixin: [],
|
|
322
|
-
status: "active",
|
|
323
|
-
},
|
|
324
|
-
{
|
|
325
|
-
action: "app.help",
|
|
326
|
-
summary: "查看当前通道可用命令",
|
|
327
|
-
terminal: ["help"],
|
|
328
|
-
weixin: ["/help"],
|
|
329
|
-
status: "active",
|
|
330
|
-
},
|
|
331
|
-
],
|
|
332
|
-
},
|
|
333
|
-
];
|
|
334
|
-
|
|
335
|
-
function listCommandGroups() {
|
|
336
|
-
return COMMAND_GROUPS.map((group) => ({
|
|
337
|
-
...group,
|
|
338
|
-
actions: group.actions.map((action) => ({ ...action })),
|
|
339
|
-
}));
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
function buildTerminalHelpText() {
|
|
281
|
+
weixin: [],
|
|
282
|
+
status: "active",
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
action: "timeline.serve",
|
|
286
|
+
summary: "启动时间轴静态页面服务",
|
|
287
|
+
terminal: ["timeline serve"],
|
|
288
|
+
terminalGroup: "timeline",
|
|
289
|
+
weixin: [],
|
|
290
|
+
status: "active",
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
action: "timeline.dev",
|
|
294
|
+
summary: "启动时间轴热更新开发服务",
|
|
295
|
+
terminal: ["timeline dev"],
|
|
296
|
+
terminalGroup: "timeline",
|
|
297
|
+
weixin: [],
|
|
298
|
+
status: "active",
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
action: "timeline.screenshot",
|
|
302
|
+
summary: "截图时间轴页面",
|
|
303
|
+
terminal: ["timeline screenshot"],
|
|
304
|
+
terminalGroup: "timeline",
|
|
305
|
+
weixin: [],
|
|
306
|
+
status: "active",
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
action: "reminder.create",
|
|
310
|
+
summary: "创建提醒并交给调度层处理",
|
|
311
|
+
terminal: ["reminder write"],
|
|
312
|
+
terminalGroup: "reminder",
|
|
313
|
+
weixin: [],
|
|
314
|
+
status: "active",
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
action: "diary.append",
|
|
318
|
+
summary: "追加一条日记记录",
|
|
319
|
+
terminal: ["diary write"],
|
|
320
|
+
terminalGroup: "diary",
|
|
321
|
+
weixin: [],
|
|
322
|
+
status: "active",
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
action: "app.help",
|
|
326
|
+
summary: "查看当前通道可用命令",
|
|
327
|
+
terminal: ["help"],
|
|
328
|
+
weixin: ["/help"],
|
|
329
|
+
status: "active",
|
|
330
|
+
},
|
|
331
|
+
],
|
|
332
|
+
},
|
|
333
|
+
];
|
|
334
|
+
|
|
335
|
+
function listCommandGroups() {
|
|
336
|
+
return COMMAND_GROUPS.map((group) => ({
|
|
337
|
+
...group,
|
|
338
|
+
actions: group.actions.map((action) => ({ ...action })),
|
|
339
|
+
}));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function buildTerminalHelpText() {
|
|
343
343
|
const lines = [
|
|
344
344
|
"用法: npm run <script>",
|
|
345
345
|
"",
|
|
@@ -350,129 +350,134 @@ function buildTerminalHelpText() {
|
|
|
350
350
|
" npm run background:install Windows 安装开机自启和周期巡检",
|
|
351
351
|
" npm run background:uninstall Windows 卸载开机自启和周期巡检",
|
|
352
352
|
];
|
|
353
|
-
|
|
354
|
-
for (const group of COMMAND_GROUPS) {
|
|
355
|
-
const activeActions = group.actions.filter((action) => action.status === "active" && action.terminal.length);
|
|
356
|
-
if (!activeActions.length) {
|
|
357
|
-
continue;
|
|
358
|
-
}
|
|
359
|
-
lines.push(`- ${group.label}`);
|
|
360
|
-
for (const action of activeActions) {
|
|
361
|
-
lines.push(` ${formatTerminalExamples(action)} ${action.summary}`);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
const plannedGroups = collectPlannedTerminalGroups();
|
|
366
|
-
if (plannedGroups.length) {
|
|
367
|
-
lines.push("");
|
|
368
|
-
lines.push("规划中的终端子命令:");
|
|
369
|
-
for (const group of plannedGroups) {
|
|
370
|
-
lines.push(`- ${group.name}`);
|
|
371
|
-
for (const action of group.actions) {
|
|
372
|
-
lines.push(` ${action.terminal.join(", ")} ${action.summary}`);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
lines.push("");
|
|
378
|
-
lines.push("微信命令映射与后续能力动作请看 README / docs。");
|
|
379
|
-
return lines.join("\n");
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
function buildWeixinHelpText() {
|
|
383
|
-
const lines = ["当前可用命令:"];
|
|
384
|
-
for (const group of COMMAND_GROUPS) {
|
|
385
|
-
const activeActions = group.actions.filter((action) => action.status === "active" && action.weixin.length);
|
|
386
|
-
if (!activeActions.length) {
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
lines.push("");
|
|
390
|
-
lines.push(`${group.label}:`);
|
|
391
|
-
for (const action of activeActions) {
|
|
392
|
-
lines.push(`- ${action.weixin.join(", ")} ${action.summary}`);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
return lines.join("\n");
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
function buildTerminalTopicHelp(topic) {
|
|
399
|
-
const normalizedTopic = normalizeTopic(topic);
|
|
400
|
-
const actions = COMMAND_GROUPS
|
|
401
|
-
.flatMap((group) => group.actions)
|
|
402
|
-
.filter((action) => normalizeTopic(action.terminalGroup) === normalizedTopic && action.terminal.length);
|
|
403
|
-
|
|
404
|
-
if (!actions.length) {
|
|
405
|
-
return "";
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
const hasPlannedOnly = actions.every((action) => action.status === "planned");
|
|
409
|
-
const lines = [
|
|
410
|
-
`用法: ${buildTopicUsage(normalizedTopic)}`,
|
|
411
|
-
"",
|
|
412
|
-
hasPlannedOnly
|
|
413
|
-
? `当前 ${normalizedTopic} 命令仍在接入中,计划中的子命令:`
|
|
414
|
-
: `当前 ${normalizedTopic} 命令:`,
|
|
415
|
-
];
|
|
416
|
-
for (const action of actions) {
|
|
417
|
-
lines.push(`- ${formatTerminalExamples(action)} ${action.summary}`);
|
|
418
|
-
}
|
|
419
|
-
return lines.join("\n");
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
function isPlannedTerminalTopic(topic) {
|
|
423
|
-
const normalizedTopic = normalizeTopic(topic);
|
|
424
|
-
return COMMAND_GROUPS
|
|
425
|
-
.flatMap((group) => group.actions)
|
|
426
|
-
.some((action) => normalizeTopic(action.terminalGroup) === normalizedTopic && action.terminal.length);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
function collectPlannedTerminalGroups() {
|
|
430
|
-
const grouped = new Map();
|
|
431
|
-
for (const action of COMMAND_GROUPS.flatMap((group) => group.actions)) {
|
|
432
|
-
if (!action.terminal.length || !action.terminalGroup || action.status !== "planned") {
|
|
433
|
-
continue;
|
|
434
|
-
}
|
|
435
|
-
const key = action.terminalGroup;
|
|
436
|
-
if (!grouped.has(key)) {
|
|
437
|
-
grouped.set(key, { name: key, actions: [] });
|
|
438
|
-
}
|
|
439
|
-
grouped.get(key).actions.push(action);
|
|
440
|
-
}
|
|
441
|
-
return Array.from(grouped.values());
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
function normalizeTopic(value) {
|
|
445
|
-
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
module.exports = {
|
|
449
|
-
buildTerminalHelpText,
|
|
450
|
-
buildTerminalTopicHelp,
|
|
451
|
-
buildWeixinHelpText,
|
|
452
|
-
isPlannedTerminalTopic,
|
|
453
|
-
listCommandGroups,
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
function formatTerminalExamples(action) {
|
|
457
|
-
const terminal = Array.isArray(action?.terminal) ? action.terminal : [];
|
|
458
|
-
if (!terminal.length) {
|
|
459
|
-
return "";
|
|
460
|
-
}
|
|
461
|
-
return terminal.map((commandText) => toNpmRunExample(commandText)).join(", ");
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
function buildTopicUsage(topic) {
|
|
465
|
-
switch (topic) {
|
|
466
|
-
case "reminder":
|
|
467
|
-
return [
|
|
468
|
-
"npm run reminder:write -- <args>",
|
|
469
|
-
"",
|
|
470
|
-
"参数:",
|
|
471
|
-
" --delay 30s|10m|1h30m|2d4h",
|
|
472
|
-
" --at 2026-04-07T21:30
|
|
473
|
-
" --text \"提醒内容\"",
|
|
474
|
-
" --user <
|
|
475
|
-
|
|
353
|
+
|
|
354
|
+
for (const group of COMMAND_GROUPS) {
|
|
355
|
+
const activeActions = group.actions.filter((action) => action.status === "active" && action.terminal.length);
|
|
356
|
+
if (!activeActions.length) {
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
lines.push(`- ${group.label}`);
|
|
360
|
+
for (const action of activeActions) {
|
|
361
|
+
lines.push(` ${formatTerminalExamples(action)} ${action.summary}`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const plannedGroups = collectPlannedTerminalGroups();
|
|
366
|
+
if (plannedGroups.length) {
|
|
367
|
+
lines.push("");
|
|
368
|
+
lines.push("规划中的终端子命令:");
|
|
369
|
+
for (const group of plannedGroups) {
|
|
370
|
+
lines.push(`- ${group.name}`);
|
|
371
|
+
for (const action of group.actions) {
|
|
372
|
+
lines.push(` ${action.terminal.join(", ")} ${action.summary}`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
lines.push("");
|
|
378
|
+
lines.push("微信命令映射与后续能力动作请看 README / docs。");
|
|
379
|
+
return lines.join("\n");
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function buildWeixinHelpText() {
|
|
383
|
+
const lines = ["当前可用命令:"];
|
|
384
|
+
for (const group of COMMAND_GROUPS) {
|
|
385
|
+
const activeActions = group.actions.filter((action) => action.status === "active" && action.weixin.length);
|
|
386
|
+
if (!activeActions.length) {
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
lines.push("");
|
|
390
|
+
lines.push(`${group.label}:`);
|
|
391
|
+
for (const action of activeActions) {
|
|
392
|
+
lines.push(`- ${action.weixin.join(", ")} ${action.summary}`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return lines.join("\n");
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function buildTerminalTopicHelp(topic) {
|
|
399
|
+
const normalizedTopic = normalizeTopic(topic);
|
|
400
|
+
const actions = COMMAND_GROUPS
|
|
401
|
+
.flatMap((group) => group.actions)
|
|
402
|
+
.filter((action) => normalizeTopic(action.terminalGroup) === normalizedTopic && action.terminal.length);
|
|
403
|
+
|
|
404
|
+
if (!actions.length) {
|
|
405
|
+
return "";
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const hasPlannedOnly = actions.every((action) => action.status === "planned");
|
|
409
|
+
const lines = [
|
|
410
|
+
`用法: ${buildTopicUsage(normalizedTopic)}`,
|
|
411
|
+
"",
|
|
412
|
+
hasPlannedOnly
|
|
413
|
+
? `当前 ${normalizedTopic} 命令仍在接入中,计划中的子命令:`
|
|
414
|
+
: `当前 ${normalizedTopic} 命令:`,
|
|
415
|
+
];
|
|
416
|
+
for (const action of actions) {
|
|
417
|
+
lines.push(`- ${formatTerminalExamples(action)} ${action.summary}`);
|
|
418
|
+
}
|
|
419
|
+
return lines.join("\n");
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function isPlannedTerminalTopic(topic) {
|
|
423
|
+
const normalizedTopic = normalizeTopic(topic);
|
|
424
|
+
return COMMAND_GROUPS
|
|
425
|
+
.flatMap((group) => group.actions)
|
|
426
|
+
.some((action) => normalizeTopic(action.terminalGroup) === normalizedTopic && action.terminal.length);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function collectPlannedTerminalGroups() {
|
|
430
|
+
const grouped = new Map();
|
|
431
|
+
for (const action of COMMAND_GROUPS.flatMap((group) => group.actions)) {
|
|
432
|
+
if (!action.terminal.length || !action.terminalGroup || action.status !== "planned") {
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
const key = action.terminalGroup;
|
|
436
|
+
if (!grouped.has(key)) {
|
|
437
|
+
grouped.set(key, { name: key, actions: [] });
|
|
438
|
+
}
|
|
439
|
+
grouped.get(key).actions.push(action);
|
|
440
|
+
}
|
|
441
|
+
return Array.from(grouped.values());
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function normalizeTopic(value) {
|
|
445
|
+
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
module.exports = {
|
|
449
|
+
buildTerminalHelpText,
|
|
450
|
+
buildTerminalTopicHelp,
|
|
451
|
+
buildWeixinHelpText,
|
|
452
|
+
isPlannedTerminalTopic,
|
|
453
|
+
listCommandGroups,
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
function formatTerminalExamples(action) {
|
|
457
|
+
const terminal = Array.isArray(action?.terminal) ? action.terminal : [];
|
|
458
|
+
if (!terminal.length) {
|
|
459
|
+
return "";
|
|
460
|
+
}
|
|
461
|
+
return terminal.map((commandText) => toNpmRunExample(commandText)).join(", ");
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function buildTopicUsage(topic) {
|
|
465
|
+
switch (topic) {
|
|
466
|
+
case "reminder":
|
|
467
|
+
return [
|
|
468
|
+
"npm run reminder:write -- <args>",
|
|
469
|
+
"",
|
|
470
|
+
"参数:",
|
|
471
|
+
" --delay 30s|10m|1h30m|2d4h",
|
|
472
|
+
" --at 2026-04-07T21:30-04:00 | 2026-04-07 21:30",
|
|
473
|
+
" --text \"提醒内容\"",
|
|
474
|
+
" --user <senderId> 可选;必须是桥实际观测到的 sender id",
|
|
475
|
+
"",
|
|
476
|
+
"补充:",
|
|
477
|
+
" 先用 npm run accounts 看可用 sender id;不要填昵称或自己猜的微信号",
|
|
478
|
+
" 当前选中的 sender id 必须已经有可用的 context_token;否则命令会直接失败",
|
|
479
|
+
" 不带 offset 的本地时间按当前 runtime timezone 解释;显式偏移时间戳按原值保留",
|
|
480
|
+
].join("\n");
|
|
476
481
|
case "diary":
|
|
477
482
|
return [
|
|
478
483
|
"npm run diary:write -- <args>",
|
|
@@ -484,29 +489,36 @@ function buildTopicUsage(topic) {
|
|
|
484
489
|
" --timeline-text \"...\" 只和 --section todo --state done 一起用;同一切换点会同步写入“时间线事实”",
|
|
485
490
|
" --title \"标题\" 默认主要给 supplement 用;其他 section 会和正文合成单行内容",
|
|
486
491
|
" --date YYYY-MM-DD 决定写入哪个日记文件",
|
|
487
|
-
" --time HH:mm
|
|
492
|
+
" --time HH:mm 可选,覆盖条目时间;todo open 时也会把它记成这条 live block 的开始时间",
|
|
488
493
|
"",
|
|
489
494
|
"示例:",
|
|
490
495
|
" npm run diary:write -- --section todo --state open --text \"把药单发给 Alex\"",
|
|
491
496
|
" npm run diary:write -- --section todo --state done --text \"收住 Codeksei 微信回复问题\" --timeline-text \"22:39-23:04 连续压测 Codeksei 微信回复链路;这条问题今晚可以先收尾。\"",
|
|
492
497
|
" npm run diary:write -- --section timeline --text \"17:30-17:58 把药单发出去了\"",
|
|
498
|
+
"",
|
|
499
|
+
"说明:",
|
|
500
|
+
" open loop / 明确待跟进 -> todo;事后完成块 -> timeline;灵感碎片 -> fragment;解释判断 -> supplement;收口带走 -> summary",
|
|
501
|
+
" 如果 todo done 省略 --timeline-text,会优先复用同一 Todo 已捕获的开始时间来补 HH:mm-HH:mm 硬事实;只有找不到开始时间时才退回成单点时间。",
|
|
502
|
+
" 不要为了记一条已完成事实而先补造一个 Todo 再立刻 done。",
|
|
503
|
+
].join("\n");
|
|
504
|
+
case "channel":
|
|
505
|
+
return [
|
|
506
|
+
"npm run channel:send-file -- --path /绝对路径 [--user <wechatUserId>]",
|
|
507
|
+
"",
|
|
508
|
+
"参数:",
|
|
509
|
+
" --path /绝对路径 要发回当前微信聊天的本地文件",
|
|
510
|
+
" --user <wechatUserId> 可选,覆盖默认接收用户",
|
|
493
511
|
].join("\n");
|
|
494
|
-
case "
|
|
495
|
-
return
|
|
496
|
-
"npm run channel:send-file -- --path /绝对路径 [--user <wechatUserId>]",
|
|
497
|
-
"",
|
|
498
|
-
"参数:",
|
|
499
|
-
" --path /绝对路径 要发回当前微信聊天的本地文件",
|
|
500
|
-
" --user <wechatUserId> 可选,覆盖默认接收用户",
|
|
501
|
-
].join("\n");
|
|
502
|
-
case "system":
|
|
503
|
-
return "npm run system:send -- <args> / npm run system:checkin";
|
|
512
|
+
case "system":
|
|
513
|
+
return "npm run system:send -- <args> / npm run system:checkin";
|
|
504
514
|
case "timeline":
|
|
505
515
|
return [
|
|
506
516
|
"npm run timeline:event -- <args> / npm run timeline:write -- <args> / npm run timeline:read -- <args> / npm run timeline:categories / npm run timeline:proposals -- <args> / npm run timeline:build / npm run timeline:serve / npm run timeline:dev / npm run timeline:screenshot -- --send",
|
|
507
517
|
"",
|
|
508
518
|
"补充:",
|
|
509
519
|
" 单条事件优先用 npm run timeline:event -- --date YYYY-MM-DD --start HH:mm --end HH:mm --title \"...\" ...,避免手写 JSON",
|
|
520
|
+
" 如果必须用 timeline:write --stdin,传完整 JSON 对象 {\"events\":[...]},不要传裸数组",
|
|
521
|
+
" 不带 offset 的本地时间按当前 timezone 解释;如果 timeline state 已声明非 legacy timezone,会优先沿用它",
|
|
510
522
|
" timeline 查分类先用 npm run timeline:categories;改已有日程前先用 npm run timeline:read -- --date YYYY-MM-DD",
|
|
511
523
|
" timeline 截图稳定入口是 npm run timeline:screenshot -- --send,它会把任务交给当前微信桥执行",
|
|
512
524
|
].join("\n");
|
|
@@ -546,31 +558,31 @@ function buildTopicUsage(topic) {
|
|
|
546
558
|
return "npm run <script>";
|
|
547
559
|
}
|
|
548
560
|
}
|
|
549
|
-
|
|
550
|
-
function toNpmRunExample(commandText) {
|
|
551
|
-
const normalized = typeof commandText === "string" ? commandText.trim() : "";
|
|
552
|
-
switch (normalized) {
|
|
553
|
-
case "login":
|
|
554
|
-
case "accounts":
|
|
555
|
-
case "start":
|
|
556
|
-
case "shared start":
|
|
557
|
-
case "shared open":
|
|
558
|
-
case "shared status":
|
|
559
|
-
case "doctor":
|
|
560
|
-
case "help":
|
|
561
|
-
return `npm run ${normalized.replace(" ", ":")}`;
|
|
562
|
-
case "start --checkin":
|
|
563
|
-
return "npm run start:checkin";
|
|
564
|
-
case "reminder write":
|
|
565
|
-
return "npm run reminder:write -- <args>";
|
|
566
|
-
case "diary write":
|
|
567
|
-
return "npm run diary:write -- <args>";
|
|
568
|
-
case "channel send-file":
|
|
569
|
-
return "npm run channel:send-file -- --path /绝对路径";
|
|
570
|
-
case "system send":
|
|
571
|
-
return "npm run system:send -- <args>";
|
|
572
|
-
case "system checkin-poller":
|
|
573
|
-
return "npm run system:checkin";
|
|
561
|
+
|
|
562
|
+
function toNpmRunExample(commandText) {
|
|
563
|
+
const normalized = typeof commandText === "string" ? commandText.trim() : "";
|
|
564
|
+
switch (normalized) {
|
|
565
|
+
case "login":
|
|
566
|
+
case "accounts":
|
|
567
|
+
case "start":
|
|
568
|
+
case "shared start":
|
|
569
|
+
case "shared open":
|
|
570
|
+
case "shared status":
|
|
571
|
+
case "doctor":
|
|
572
|
+
case "help":
|
|
573
|
+
return `npm run ${normalized.replace(" ", ":")}`;
|
|
574
|
+
case "start --checkin":
|
|
575
|
+
return "npm run start:checkin";
|
|
576
|
+
case "reminder write":
|
|
577
|
+
return "npm run reminder:write -- <args>";
|
|
578
|
+
case "diary write":
|
|
579
|
+
return "npm run diary:write -- <args>";
|
|
580
|
+
case "channel send-file":
|
|
581
|
+
return "npm run channel:send-file -- --path /绝对路径";
|
|
582
|
+
case "system send":
|
|
583
|
+
return "npm run system:send -- <args>";
|
|
584
|
+
case "system checkin-poller":
|
|
585
|
+
return "npm run system:checkin";
|
|
574
586
|
case "timeline write":
|
|
575
587
|
return "npm run timeline:write -- <args>";
|
|
576
588
|
case "timeline event":
|
|
@@ -583,10 +595,10 @@ function toNpmRunExample(commandText) {
|
|
|
583
595
|
return "npm run timeline:proposals -- <args>";
|
|
584
596
|
case "timeline build":
|
|
585
597
|
return "npm run timeline:build";
|
|
586
|
-
case "timeline serve":
|
|
587
|
-
return "npm run timeline:serve";
|
|
588
|
-
case "timeline dev":
|
|
589
|
-
return "npm run timeline:dev";
|
|
598
|
+
case "timeline serve":
|
|
599
|
+
return "npm run timeline:serve";
|
|
600
|
+
case "timeline dev":
|
|
601
|
+
return "npm run timeline:dev";
|
|
590
602
|
case "timeline screenshot":
|
|
591
603
|
return "npm run timeline:screenshot -- --send";
|
|
592
604
|
case "project radar":
|