codeksei 0.1.0
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 -0
- package/README.en.md +215 -0
- package/README.md +259 -0
- package/bin/codeksei.js +10 -0
- package/bin/cyberboss.js +11 -0
- package/package.json +86 -0
- package/scripts/install-background-tasks.ps1 +135 -0
- package/scripts/open_shared_wechat_thread.sh +94 -0
- package/scripts/open_wechat_thread.sh +117 -0
- package/scripts/shared-common.js +791 -0
- package/scripts/shared-open.js +46 -0
- package/scripts/shared-start.js +41 -0
- package/scripts/shared-status.js +74 -0
- package/scripts/shared-supervisor.js +141 -0
- package/scripts/shared-task-runner.ps1 +87 -0
- package/scripts/shared-watchdog.js +290 -0
- package/scripts/show_shared_status.sh +53 -0
- package/scripts/start_shared_app_server.sh +65 -0
- package/scripts/start_shared_wechat.sh +108 -0
- package/scripts/timeline-screenshot.sh +15 -0
- package/scripts/uninstall-background-tasks.ps1 +23 -0
- package/src/adapters/channel/weixin/account-store.js +135 -0
- package/src/adapters/channel/weixin/api-v2.js +258 -0
- package/src/adapters/channel/weixin/api.js +180 -0
- package/src/adapters/channel/weixin/context-token-store.js +84 -0
- package/src/adapters/channel/weixin/index.js +605 -0
- package/src/adapters/channel/weixin/legacy.js +567 -0
- package/src/adapters/channel/weixin/login-common.js +63 -0
- package/src/adapters/channel/weixin/login-legacy.js +124 -0
- package/src/adapters/channel/weixin/login-v2.js +186 -0
- package/src/adapters/channel/weixin/media-mime.js +22 -0
- package/src/adapters/channel/weixin/media-receive.js +370 -0
- package/src/adapters/channel/weixin/media-send.js +331 -0
- package/src/adapters/channel/weixin/message-utils-v2.js +282 -0
- package/src/adapters/channel/weixin/message-utils.js +199 -0
- package/src/adapters/channel/weixin/protocol.js +77 -0
- package/src/adapters/channel/weixin/redact.js +41 -0
- package/src/adapters/channel/weixin/reminder-queue-store.js +101 -0
- package/src/adapters/channel/weixin/sync-buffer-store.js +35 -0
- package/src/adapters/runtime/codex/events.js +252 -0
- package/src/adapters/runtime/codex/index.js +502 -0
- package/src/adapters/runtime/codex/message-utils.js +141 -0
- package/src/adapters/runtime/codex/model-catalog.js +106 -0
- package/src/adapters/runtime/codex/protocol-leak-monitor.js +75 -0
- package/src/adapters/runtime/codex/rpc-client.js +443 -0
- package/src/adapters/runtime/codex/session-store.js +376 -0
- package/src/app/channel-send-file-cli.js +57 -0
- package/src/app/diary-write-cli.js +620 -0
- package/src/app/note-auto-cli.js +201 -0
- package/src/app/note-sync-cli.js +130 -0
- package/src/app/project-radar-cli.js +165 -0
- package/src/app/reminder-write-cli.js +210 -0
- package/src/app/review-cli.js +134 -0
- package/src/app/system-checkin-poller.js +100 -0
- package/src/app/system-send-cli.js +129 -0
- package/src/app/timeline-event-cli.js +273 -0
- package/src/app/timeline-screenshot-cli.js +109 -0
- package/src/core/app.js +1810 -0
- package/src/core/branding.js +167 -0
- package/src/core/command-registry.js +609 -0
- package/src/core/config.js +84 -0
- package/src/core/default-targets.js +163 -0
- package/src/core/durable-note-schema.js +325 -0
- package/src/core/instructions-template.js +31 -0
- package/src/core/note-sync.js +433 -0
- package/src/core/project-radar.js +402 -0
- package/src/core/review-semantic.js +524 -0
- package/src/core/review.js +1081 -0
- package/src/core/shared-bridge-heartbeat.js +140 -0
- package/src/core/stream-delivery.js +990 -0
- package/src/core/system-message-dispatcher.js +68 -0
- package/src/core/system-message-queue-store.js +128 -0
- package/src/core/thread-state-store.js +135 -0
- package/src/core/timeline-screenshot-queue-store.js +134 -0
- package/src/core/workspace-alias.js +163 -0
- package/src/core/workspace-bootstrap.js +338 -0
- package/src/index.js +270 -0
- package/src/integrations/timeline/index.js +191 -0
- package/templates/weixin-instructions.md +53 -0
- package/templates/weixin-operations.md +69 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const { normalizeModelCatalog } = require("./model-catalog");
|
|
4
|
+
|
|
5
|
+
class SessionStore {
|
|
6
|
+
constructor({ filePath }) {
|
|
7
|
+
this.filePath = filePath;
|
|
8
|
+
this.state = createEmptyState();
|
|
9
|
+
this.ensureParentDirectory();
|
|
10
|
+
this.load();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
ensureParentDirectory() {
|
|
14
|
+
fs.mkdirSync(path.dirname(this.filePath), { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
load() {
|
|
18
|
+
try {
|
|
19
|
+
const raw = fs.readFileSync(this.filePath, "utf8");
|
|
20
|
+
const parsed = JSON.parse(raw);
|
|
21
|
+
if (parsed && typeof parsed === "object" && parsed.bindings) {
|
|
22
|
+
this.state = {
|
|
23
|
+
...createEmptyState(),
|
|
24
|
+
...parsed,
|
|
25
|
+
bindings: parsed.bindings || {},
|
|
26
|
+
approvalCommandAllowlistByWorkspaceRoot: parsed.approvalCommandAllowlistByWorkspaceRoot || {},
|
|
27
|
+
approvalPromptStateByThreadId: parsed.approvalPromptStateByThreadId || {},
|
|
28
|
+
availableModelCatalog: parsed.availableModelCatalog || {
|
|
29
|
+
models: [],
|
|
30
|
+
updatedAt: "",
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
this.state = createEmptyState();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
save() {
|
|
40
|
+
fs.writeFileSync(this.filePath, JSON.stringify(this.state, null, 2));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
getBinding(bindingKey) {
|
|
44
|
+
return this.state.bindings[bindingKey] || null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
listBindings() {
|
|
48
|
+
return Object.entries(this.state.bindings || {}).map(([bindingKey, binding]) => ({
|
|
49
|
+
bindingKey,
|
|
50
|
+
...(binding || {}),
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
getActiveWorkspaceRoot(bindingKey) {
|
|
55
|
+
return normalizeValue(this.state.bindings[bindingKey]?.activeWorkspaceRoot);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
updateBinding(bindingKey, nextBinding) {
|
|
59
|
+
this.state.bindings[bindingKey] = {
|
|
60
|
+
...(this.state.bindings[bindingKey] || {}),
|
|
61
|
+
...(nextBinding || {}),
|
|
62
|
+
};
|
|
63
|
+
this.save();
|
|
64
|
+
return this.state.bindings[bindingKey];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getThreadIdForWorkspace(bindingKey, workspaceRoot) {
|
|
68
|
+
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
69
|
+
if (!normalizedWorkspaceRoot) {
|
|
70
|
+
return "";
|
|
71
|
+
}
|
|
72
|
+
return this.state.bindings[bindingKey]?.threadIdByWorkspaceRoot?.[normalizedWorkspaceRoot] || "";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
setThreadIdForWorkspace(bindingKey, workspaceRoot, threadId, extra = {}) {
|
|
76
|
+
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
77
|
+
const normalizedThreadId = normalizeValue(threadId);
|
|
78
|
+
if (!normalizedWorkspaceRoot) {
|
|
79
|
+
return this.getBinding(bindingKey);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const current = this.getBinding(bindingKey) || {};
|
|
83
|
+
const threadIdByWorkspaceRoot = {
|
|
84
|
+
...getThreadMap(current),
|
|
85
|
+
[normalizedWorkspaceRoot]: normalizedThreadId,
|
|
86
|
+
};
|
|
87
|
+
const workspaceBootstrapThreadIdByWorkspaceRoot = {
|
|
88
|
+
...getWorkspaceBootstrapThreadMap(current),
|
|
89
|
+
[normalizedWorkspaceRoot]:
|
|
90
|
+
getWorkspaceBootstrapThreadMap(current)[normalizedWorkspaceRoot] === normalizedThreadId
|
|
91
|
+
? normalizedThreadId
|
|
92
|
+
: "",
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return this.updateBinding(bindingKey, {
|
|
96
|
+
...current,
|
|
97
|
+
...extra,
|
|
98
|
+
activeWorkspaceRoot: normalizedWorkspaceRoot,
|
|
99
|
+
threadIdByWorkspaceRoot,
|
|
100
|
+
workspaceBootstrapThreadIdByWorkspaceRoot,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
getCodexParamsForWorkspace(bindingKey, workspaceRoot) {
|
|
105
|
+
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
106
|
+
if (!normalizedWorkspaceRoot) {
|
|
107
|
+
return { model: "" };
|
|
108
|
+
}
|
|
109
|
+
const current = this.getBinding(bindingKey) || {};
|
|
110
|
+
const codexParamsByWorkspaceRoot = getCodexParamsMap(current);
|
|
111
|
+
const entry = codexParamsByWorkspaceRoot[normalizedWorkspaceRoot];
|
|
112
|
+
return {
|
|
113
|
+
model: normalizeValue(entry?.model),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
setCodexParamsForWorkspace(bindingKey, workspaceRoot, { model = "" }) {
|
|
118
|
+
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
119
|
+
if (!normalizedWorkspaceRoot) {
|
|
120
|
+
return this.getBinding(bindingKey);
|
|
121
|
+
}
|
|
122
|
+
const current = this.getBinding(bindingKey) || {};
|
|
123
|
+
const codexParamsByWorkspaceRoot = {
|
|
124
|
+
...getCodexParamsMap(current),
|
|
125
|
+
[normalizedWorkspaceRoot]: {
|
|
126
|
+
model: normalizeValue(model),
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
return this.updateBinding(bindingKey, {
|
|
130
|
+
...current,
|
|
131
|
+
codexParamsByWorkspaceRoot,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
clearThreadIdForWorkspace(bindingKey, workspaceRoot) {
|
|
136
|
+
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
137
|
+
if (!normalizedWorkspaceRoot) {
|
|
138
|
+
return this.getBinding(bindingKey);
|
|
139
|
+
}
|
|
140
|
+
const current = this.getBinding(bindingKey) || {};
|
|
141
|
+
const threadIdByWorkspaceRoot = {
|
|
142
|
+
...getThreadMap(current),
|
|
143
|
+
[normalizedWorkspaceRoot]: "",
|
|
144
|
+
};
|
|
145
|
+
const workspaceBootstrapThreadIdByWorkspaceRoot = {
|
|
146
|
+
...getWorkspaceBootstrapThreadMap(current),
|
|
147
|
+
[normalizedWorkspaceRoot]: "",
|
|
148
|
+
};
|
|
149
|
+
return this.updateBinding(bindingKey, {
|
|
150
|
+
...current,
|
|
151
|
+
threadIdByWorkspaceRoot,
|
|
152
|
+
workspaceBootstrapThreadIdByWorkspaceRoot,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
setActiveWorkspaceRoot(bindingKey, workspaceRoot) {
|
|
157
|
+
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
158
|
+
if (!normalizedWorkspaceRoot) {
|
|
159
|
+
return this.getBinding(bindingKey);
|
|
160
|
+
}
|
|
161
|
+
return this.updateBinding(bindingKey, {
|
|
162
|
+
activeWorkspaceRoot: normalizedWorkspaceRoot,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
listWorkspaceRoots(bindingKey) {
|
|
167
|
+
const current = this.getBinding(bindingKey) || {};
|
|
168
|
+
return Object.keys(getThreadMap(current));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
findBindingForThreadId(threadId) {
|
|
172
|
+
const normalizedThreadId = normalizeValue(threadId);
|
|
173
|
+
if (!normalizedThreadId) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
for (const [bindingKey, binding] of Object.entries(this.state.bindings || {})) {
|
|
177
|
+
for (const [workspaceRoot, candidateThreadId] of Object.entries(getThreadMap(binding))) {
|
|
178
|
+
if (normalizeValue(candidateThreadId) === normalizedThreadId) {
|
|
179
|
+
return {
|
|
180
|
+
bindingKey,
|
|
181
|
+
workspaceRoot: normalizeValue(workspaceRoot),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
hasWorkspaceBootstrapForThread(bindingKey, workspaceRoot, threadId) {
|
|
190
|
+
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
191
|
+
const normalizedThreadId = normalizeValue(threadId);
|
|
192
|
+
if (!normalizedWorkspaceRoot || !normalizedThreadId) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
const current = this.getBinding(bindingKey) || {};
|
|
196
|
+
return getWorkspaceBootstrapThreadMap(current)[normalizedWorkspaceRoot] === normalizedThreadId;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
rememberWorkspaceBootstrapForThread(bindingKey, workspaceRoot, threadId) {
|
|
200
|
+
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
201
|
+
const normalizedThreadId = normalizeValue(threadId);
|
|
202
|
+
if (!normalizedWorkspaceRoot || !normalizedThreadId) {
|
|
203
|
+
return this.getBinding(bindingKey);
|
|
204
|
+
}
|
|
205
|
+
const current = this.getBinding(bindingKey) || {};
|
|
206
|
+
const workspaceBootstrapThreadIdByWorkspaceRoot = {
|
|
207
|
+
...getWorkspaceBootstrapThreadMap(current),
|
|
208
|
+
[normalizedWorkspaceRoot]: normalizedThreadId,
|
|
209
|
+
};
|
|
210
|
+
return this.updateBinding(bindingKey, {
|
|
211
|
+
...current,
|
|
212
|
+
workspaceBootstrapThreadIdByWorkspaceRoot,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
getApprovalCommandAllowlistForWorkspace(workspaceRoot) {
|
|
217
|
+
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
218
|
+
if (!normalizedWorkspaceRoot) {
|
|
219
|
+
return [];
|
|
220
|
+
}
|
|
221
|
+
const raw = this.state.approvalCommandAllowlistByWorkspaceRoot?.[normalizedWorkspaceRoot];
|
|
222
|
+
if (!Array.isArray(raw)) {
|
|
223
|
+
return [];
|
|
224
|
+
}
|
|
225
|
+
return raw
|
|
226
|
+
.filter((entry) => Array.isArray(entry))
|
|
227
|
+
.map((entry) => entry.map((part) => normalizeValue(part)).filter(Boolean))
|
|
228
|
+
.filter((entry) => entry.length);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
rememberApprovalPrefixForWorkspace(workspaceRoot, commandTokens) {
|
|
232
|
+
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
233
|
+
const normalizedTokens = normalizeCommandTokens(commandTokens);
|
|
234
|
+
if (!normalizedWorkspaceRoot || !normalizedTokens.length) {
|
|
235
|
+
return this.getApprovalCommandAllowlistForWorkspace(workspaceRoot);
|
|
236
|
+
}
|
|
237
|
+
const current = this.getApprovalCommandAllowlistForWorkspace(normalizedWorkspaceRoot);
|
|
238
|
+
if (!current.some((entry) => isSameTokenList(entry, normalizedTokens))) {
|
|
239
|
+
current.push(normalizedTokens);
|
|
240
|
+
this.state.approvalCommandAllowlistByWorkspaceRoot = {
|
|
241
|
+
...(this.state.approvalCommandAllowlistByWorkspaceRoot || {}),
|
|
242
|
+
[normalizedWorkspaceRoot]: current,
|
|
243
|
+
};
|
|
244
|
+
this.save();
|
|
245
|
+
}
|
|
246
|
+
return current;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
getApprovalPromptState(threadId) {
|
|
250
|
+
const normalizedThreadId = normalizeValue(threadId);
|
|
251
|
+
if (!normalizedThreadId) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
const raw = this.state.approvalPromptStateByThreadId?.[normalizedThreadId];
|
|
255
|
+
if (!raw || typeof raw !== "object") {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
requestId: normalizeValue(raw.requestId),
|
|
260
|
+
signature: normalizeValue(raw.signature),
|
|
261
|
+
promptedAt: normalizeValue(raw.promptedAt),
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
rememberApprovalPrompt(threadId, requestId, signature = "") {
|
|
266
|
+
const normalizedThreadId = normalizeValue(threadId);
|
|
267
|
+
const normalizedRequestId = normalizeValue(requestId);
|
|
268
|
+
const normalizedSignature = normalizeValue(signature);
|
|
269
|
+
if (!normalizedThreadId || !normalizedRequestId) {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
this.state.approvalPromptStateByThreadId = {
|
|
273
|
+
...(this.state.approvalPromptStateByThreadId || {}),
|
|
274
|
+
[normalizedThreadId]: {
|
|
275
|
+
requestId: normalizedRequestId,
|
|
276
|
+
signature: normalizedSignature,
|
|
277
|
+
promptedAt: new Date().toISOString(),
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
this.save();
|
|
281
|
+
return this.getApprovalPromptState(normalizedThreadId);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
clearApprovalPrompt(threadId) {
|
|
285
|
+
const normalizedThreadId = normalizeValue(threadId);
|
|
286
|
+
if (!normalizedThreadId || !this.state.approvalPromptStateByThreadId?.[normalizedThreadId]) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
const next = {
|
|
290
|
+
...(this.state.approvalPromptStateByThreadId || {}),
|
|
291
|
+
};
|
|
292
|
+
delete next[normalizedThreadId];
|
|
293
|
+
this.state.approvalPromptStateByThreadId = next;
|
|
294
|
+
this.save();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
getAvailableModelCatalog() {
|
|
298
|
+
const raw = this.state.availableModelCatalog;
|
|
299
|
+
if (!raw || typeof raw !== "object") {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
const models = normalizeModelCatalog(raw.models);
|
|
303
|
+
if (!models.length) {
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
const updatedAt = normalizeValue(raw.updatedAt);
|
|
307
|
+
return { models, updatedAt };
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
setAvailableModelCatalog(models) {
|
|
311
|
+
const normalizedModels = normalizeModelCatalog(models);
|
|
312
|
+
if (!normalizedModels.length) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
this.state.availableModelCatalog = {
|
|
316
|
+
models: normalizedModels,
|
|
317
|
+
updatedAt: new Date().toISOString(),
|
|
318
|
+
};
|
|
319
|
+
this.save();
|
|
320
|
+
return this.state.availableModelCatalog;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
buildBindingKey({ workspaceId, accountId, senderId }) {
|
|
324
|
+
return `${normalizeValue(workspaceId)}:${normalizeValue(accountId)}:${normalizeValue(senderId)}`;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function createEmptyState() {
|
|
329
|
+
return {
|
|
330
|
+
bindings: {},
|
|
331
|
+
approvalCommandAllowlistByWorkspaceRoot: {},
|
|
332
|
+
approvalPromptStateByThreadId: {},
|
|
333
|
+
availableModelCatalog: {
|
|
334
|
+
models: [],
|
|
335
|
+
updatedAt: "",
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function normalizeValue(value) {
|
|
341
|
+
return typeof value === "string" ? value.trim() : "";
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function getThreadMap(binding) {
|
|
345
|
+
return binding?.threadIdByWorkspaceRoot && typeof binding.threadIdByWorkspaceRoot === "object"
|
|
346
|
+
? binding.threadIdByWorkspaceRoot
|
|
347
|
+
: {};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function getCodexParamsMap(binding) {
|
|
351
|
+
return binding?.codexParamsByWorkspaceRoot && typeof binding.codexParamsByWorkspaceRoot === "object"
|
|
352
|
+
? binding.codexParamsByWorkspaceRoot
|
|
353
|
+
: {};
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function getWorkspaceBootstrapThreadMap(binding) {
|
|
357
|
+
return binding?.workspaceBootstrapThreadIdByWorkspaceRoot
|
|
358
|
+
&& typeof binding.workspaceBootstrapThreadIdByWorkspaceRoot === "object"
|
|
359
|
+
? binding.workspaceBootstrapThreadIdByWorkspaceRoot
|
|
360
|
+
: {};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function normalizeCommandTokens(tokens) {
|
|
364
|
+
return Array.isArray(tokens)
|
|
365
|
+
? tokens.map((part) => normalizeValue(part)).filter(Boolean)
|
|
366
|
+
: [];
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function isSameTokenList(left, right) {
|
|
370
|
+
if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) {
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
return left.every((value, index) => value === right[index]);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
module.exports = { SessionStore };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
async function runChannelSendFileCommand(app) {
|
|
2
|
+
const args = process.argv.slice(4);
|
|
3
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
4
|
+
printHelp();
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const options = parseArgs(args);
|
|
9
|
+
if (!options.path) {
|
|
10
|
+
throw new Error("缺少 --path,指定要发回微信的本地文件路径");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const result = await app.sendLocalFileToCurrentChat({
|
|
14
|
+
senderId: options.user,
|
|
15
|
+
filePath: options.path,
|
|
16
|
+
});
|
|
17
|
+
console.log(`file sent: ${result.filePath}`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function parseArgs(args) {
|
|
21
|
+
const options = {
|
|
22
|
+
path: "",
|
|
23
|
+
user: "",
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
27
|
+
const arg = String(args[index] || "");
|
|
28
|
+
if (arg === "--path") {
|
|
29
|
+
options.path = String(args[index + 1] || "");
|
|
30
|
+
index += 1;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (arg === "--user") {
|
|
34
|
+
options.user = String(args[index + 1] || "");
|
|
35
|
+
index += 1;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
throw new Error(`未知参数: ${arg}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return options;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function printHelp() {
|
|
45
|
+
console.log([
|
|
46
|
+
"用法: npm run channel:send-file -- --path /绝对路径 [--user <wechatUserId>]",
|
|
47
|
+
"",
|
|
48
|
+
"参数:",
|
|
49
|
+
" --path /绝对路径 要发回当前微信聊天的本地文件",
|
|
50
|
+
" --user <wechatUserId> 可选,覆盖默认接收用户",
|
|
51
|
+
"",
|
|
52
|
+
"示例:",
|
|
53
|
+
" npm run channel:send-file -- --path /Users/name/project/README.md",
|
|
54
|
+
].join("\n"));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = { runChannelSendFileCommand };
|