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,77 +1,77 @@
|
|
|
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
|
-
|
|
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
75
|
setThreadIdForWorkspace(bindingKey, workspaceRoot, threadId, extra = {}) {
|
|
76
76
|
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
77
77
|
const normalizedThreadId = normalizeValue(threadId);
|
|
@@ -100,38 +100,38 @@ class SessionStore {
|
|
|
100
100
|
workspaceBootstrapThreadIdByWorkspaceRoot,
|
|
101
101
|
});
|
|
102
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
|
-
|
|
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
135
|
clearThreadIdForWorkspace(bindingKey, workspaceRoot) {
|
|
136
136
|
const normalizedWorkspaceRoot = normalizeValue(workspaceRoot);
|
|
137
137
|
if (!normalizedWorkspaceRoot) {
|
|
@@ -152,37 +152,37 @@ class SessionStore {
|
|
|
152
152
|
workspaceBootstrapThreadIdByWorkspaceRoot,
|
|
153
153
|
});
|
|
154
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
|
-
|
|
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
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
|
-
}
|
|
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
186
|
return null;
|
|
187
187
|
}
|
|
188
188
|
|
|
@@ -212,141 +212,141 @@ class SessionStore {
|
|
|
212
212
|
workspaceBootstrapThreadIdByWorkspaceRoot,
|
|
213
213
|
});
|
|
214
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
|
-
|
|
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
350
|
function getCodexParamsMap(binding) {
|
|
351
351
|
return binding?.codexParamsByWorkspaceRoot && typeof binding.codexParamsByWorkspaceRoot === "object"
|
|
352
352
|
? binding.codexParamsByWorkspaceRoot
|
|
@@ -359,18 +359,18 @@ function getWorkspaceBootstrapThreadMap(binding) {
|
|
|
359
359
|
? binding.workspaceBootstrapThreadIdByWorkspaceRoot
|
|
360
360
|
: {};
|
|
361
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 };
|
|
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 };
|