telecodex 0.1.1 → 0.1.2
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/README.md +10 -3
- package/dist/bot/commandSupport.js +3 -1
- package/dist/bot/createBot.js +16 -2
- package/dist/bot/handlers/projectHandlers.js +67 -8
- package/dist/bot/topicCleanup.js +80 -0
- package/dist/codex/sessionCatalog.js +215 -0
- package/dist/config.js +0 -1
- package/dist/runtime/appPaths.js +4 -1
- package/dist/runtime/bootstrap.js +11 -7
- package/dist/runtime/startTelecodex.js +5 -0
- package/dist/store/fileState.js +370 -0
- package/dist/store/legacyMigration.js +160 -0
- package/dist/store/projects.js +11 -33
- package/dist/store/sessions.js +138 -210
- package/package.json +2 -2
- package/dist/store/db.js +0 -267
package/dist/store/sessions.js
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
import { DEFAULT_SESSION_PROFILE,
|
|
1
|
+
import { DEFAULT_SESSION_PROFILE, } from "../config.js";
|
|
2
2
|
export const BINDING_CODE_TTL_MS = 15 * 60 * 1000;
|
|
3
3
|
export const BINDING_CODE_MAX_ATTEMPTS = 5;
|
|
4
4
|
export class SessionStore {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
storage;
|
|
6
|
+
runtimeStateBySession = new Map();
|
|
7
|
+
outputMessageBySession = new Map();
|
|
8
|
+
queueBySession = new Map();
|
|
9
|
+
nextQueuedInputId = 1;
|
|
10
|
+
constructor(storage) {
|
|
11
|
+
this.storage = storage;
|
|
8
12
|
}
|
|
9
13
|
getAppState(key) {
|
|
10
|
-
|
|
11
|
-
return row?.value ?? null;
|
|
14
|
+
return this.storage.getAppState(key);
|
|
12
15
|
}
|
|
13
16
|
setAppState(key, value) {
|
|
14
|
-
this.
|
|
15
|
-
.prepare(`INSERT INTO app_state (key, value, updated_at)
|
|
16
|
-
VALUES (?, ?, ?)
|
|
17
|
-
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at`)
|
|
18
|
-
.run(key, value, new Date().toISOString());
|
|
17
|
+
this.storage.setAppState(key, value);
|
|
19
18
|
}
|
|
20
19
|
deleteAppState(key) {
|
|
21
|
-
this.
|
|
20
|
+
this.storage.deleteAppState(key);
|
|
22
21
|
}
|
|
23
22
|
getAuthorizedUserId() {
|
|
24
23
|
const value = this.getAppState("authorized_user_id");
|
|
@@ -123,11 +122,11 @@ export class SessionStore {
|
|
|
123
122
|
const existing = this.getAuthorizedUserId();
|
|
124
123
|
if (existing != null)
|
|
125
124
|
return existing;
|
|
126
|
-
this.
|
|
125
|
+
this.setAppState("authorized_user_id", String(userId));
|
|
126
|
+
this.clearBindingCode();
|
|
127
127
|
const current = this.getAuthorizedUserId();
|
|
128
128
|
if (current == null)
|
|
129
129
|
throw new Error("Failed to persist authorized Telegram user id");
|
|
130
|
-
this.clearBindingCode();
|
|
131
130
|
return current;
|
|
132
131
|
}
|
|
133
132
|
rebindAuthorizedUserId(userId) {
|
|
@@ -143,237 +142,201 @@ export class SessionStore {
|
|
|
143
142
|
if (existing)
|
|
144
143
|
return existing;
|
|
145
144
|
const now = new Date().toISOString();
|
|
146
|
-
this.
|
|
147
|
-
.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
145
|
+
this.storage.putSession({
|
|
146
|
+
sessionKey: input.sessionKey,
|
|
147
|
+
chatId: input.chatId,
|
|
148
|
+
messageThreadId: input.messageThreadId,
|
|
149
|
+
telegramTopicName: input.telegramTopicName ?? null,
|
|
150
|
+
codexThreadId: null,
|
|
151
|
+
cwd: input.defaultCwd,
|
|
152
|
+
model: input.defaultModel,
|
|
153
|
+
sandboxMode: DEFAULT_SESSION_PROFILE.sandboxMode,
|
|
154
|
+
approvalPolicy: DEFAULT_SESSION_PROFILE.approvalPolicy,
|
|
155
|
+
reasoningEffort: null,
|
|
156
|
+
webSearchMode: null,
|
|
157
|
+
networkAccessEnabled: true,
|
|
158
|
+
skipGitRepoCheck: true,
|
|
159
|
+
additionalDirectories: [],
|
|
160
|
+
outputSchema: null,
|
|
161
|
+
createdAt: now,
|
|
162
|
+
updatedAt: now,
|
|
163
|
+
});
|
|
151
164
|
const created = this.get(input.sessionKey);
|
|
152
165
|
if (!created)
|
|
153
166
|
throw new Error("Session insert failed");
|
|
154
167
|
return created;
|
|
155
168
|
}
|
|
156
169
|
get(sessionKey) {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
.get(sessionKey);
|
|
160
|
-
return row ? mapSessionRow(row) : null;
|
|
170
|
+
const stored = this.storage.getSession(sessionKey);
|
|
171
|
+
return mapStoredSession(stored, this.runtimeStateBySession.get(sessionKey), this.outputMessageBySession.get(sessionKey));
|
|
161
172
|
}
|
|
162
173
|
getByThreadId(threadId) {
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
.get(threadId);
|
|
166
|
-
return row ? mapSessionRow(row) : null;
|
|
174
|
+
const stored = this.storage.getSessionByThreadId(threadId);
|
|
175
|
+
return stored ? mapStoredSession(stored, this.runtimeStateBySession.get(stored.sessionKey), this.outputMessageBySession.get(stored.sessionKey)) : null;
|
|
167
176
|
}
|
|
168
177
|
listTopicSessions() {
|
|
169
|
-
|
|
170
|
-
.
|
|
171
|
-
.
|
|
172
|
-
|
|
178
|
+
return this.storage
|
|
179
|
+
.listSessions()
|
|
180
|
+
.filter((session) => session.messageThreadId != null)
|
|
181
|
+
.map((session) => mapStoredSession(session, this.runtimeStateBySession.get(session.sessionKey), this.outputMessageBySession.get(session.sessionKey)))
|
|
182
|
+
.filter((session) => session != null);
|
|
173
183
|
}
|
|
174
184
|
remove(sessionKey) {
|
|
175
|
-
this.
|
|
176
|
-
this.
|
|
185
|
+
this.queueBySession.delete(sessionKey);
|
|
186
|
+
this.runtimeStateBySession.delete(sessionKey);
|
|
187
|
+
this.outputMessageBySession.delete(sessionKey);
|
|
188
|
+
this.storage.removeSession(sessionKey);
|
|
177
189
|
}
|
|
178
190
|
enqueueInput(sessionKey, input) {
|
|
179
191
|
const now = new Date().toISOString();
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
const queued = {
|
|
193
|
+
id: this.nextQueuedInputId,
|
|
194
|
+
sessionKey,
|
|
195
|
+
text: formatCodexInputPreview(input),
|
|
196
|
+
input: cloneStoredCodexInput(input),
|
|
197
|
+
createdAt: now,
|
|
198
|
+
updatedAt: now,
|
|
199
|
+
};
|
|
200
|
+
this.nextQueuedInputId += 1;
|
|
201
|
+
const queue = this.queueBySession.get(sessionKey) ?? [];
|
|
202
|
+
queue.push(queued);
|
|
203
|
+
this.queueBySession.set(sessionKey, queue);
|
|
204
|
+
return cloneQueuedInput(queued);
|
|
190
205
|
}
|
|
191
206
|
getQueuedInput(id) {
|
|
192
|
-
const
|
|
193
|
-
|
|
207
|
+
for (const queue of this.queueBySession.values()) {
|
|
208
|
+
const match = queue.find((item) => item.id === id);
|
|
209
|
+
if (match)
|
|
210
|
+
return cloneQueuedInput(match);
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
194
213
|
}
|
|
195
214
|
getQueuedInputCount(sessionKey) {
|
|
196
|
-
|
|
197
|
-
.prepare("SELECT COUNT(*) AS count FROM queued_inputs WHERE session_key = ?")
|
|
198
|
-
.get(sessionKey);
|
|
199
|
-
return row?.count ?? 0;
|
|
215
|
+
return this.queueBySession.get(sessionKey)?.length ?? 0;
|
|
200
216
|
}
|
|
201
217
|
peekNextQueuedInput(sessionKey) {
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return row ? mapQueuedInputRow(row) : null;
|
|
218
|
+
const queue = this.queueBySession.get(sessionKey);
|
|
219
|
+
const [next] = queue ?? [];
|
|
220
|
+
return next ? cloneQueuedInput(next) : null;
|
|
206
221
|
}
|
|
207
222
|
listQueuedInputs(sessionKey, limit = 5) {
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
.all(sessionKey, limit);
|
|
211
|
-
return rows.map(mapQueuedInputRow);
|
|
223
|
+
const queue = this.queueBySession.get(sessionKey) ?? [];
|
|
224
|
+
return queue.slice(0, limit).map(cloneQueuedInput);
|
|
212
225
|
}
|
|
213
226
|
removeQueuedInput(id) {
|
|
214
|
-
|
|
227
|
+
for (const [sessionKey, queue] of this.queueBySession.entries()) {
|
|
228
|
+
const index = queue.findIndex((item) => item.id === id);
|
|
229
|
+
if (index < 0)
|
|
230
|
+
continue;
|
|
231
|
+
queue.splice(index, 1);
|
|
232
|
+
if (queue.length === 0) {
|
|
233
|
+
this.queueBySession.delete(sessionKey);
|
|
234
|
+
}
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
215
237
|
}
|
|
216
238
|
removeQueuedInputForSession(sessionKey, id) {
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
239
|
+
const queue = this.queueBySession.get(sessionKey);
|
|
240
|
+
if (!queue)
|
|
241
|
+
return false;
|
|
242
|
+
const index = queue.findIndex((item) => item.id === id);
|
|
243
|
+
if (index < 0)
|
|
244
|
+
return false;
|
|
245
|
+
queue.splice(index, 1);
|
|
246
|
+
if (queue.length === 0) {
|
|
247
|
+
this.queueBySession.delete(sessionKey);
|
|
248
|
+
}
|
|
249
|
+
return true;
|
|
221
250
|
}
|
|
222
251
|
clearQueuedInputs(sessionKey) {
|
|
223
|
-
const
|
|
224
|
-
|
|
252
|
+
const queue = this.queueBySession.get(sessionKey) ?? [];
|
|
253
|
+
this.queueBySession.delete(sessionKey);
|
|
254
|
+
return queue.length;
|
|
225
255
|
}
|
|
226
256
|
bindThread(sessionKey, threadId) {
|
|
227
|
-
this.
|
|
228
|
-
|
|
257
|
+
this.patchDurableSession(sessionKey, {
|
|
258
|
+
codexThreadId: threadId,
|
|
229
259
|
});
|
|
230
260
|
}
|
|
231
261
|
setTelegramTopicName(sessionKey, topicName) {
|
|
232
|
-
this.
|
|
262
|
+
this.patchDurableSession(sessionKey, {
|
|
263
|
+
telegramTopicName: topicName,
|
|
264
|
+
});
|
|
233
265
|
}
|
|
234
266
|
setRuntimeState(sessionKey, state) {
|
|
235
|
-
this.
|
|
236
|
-
runtime_status: state.status,
|
|
237
|
-
runtime_status_detail: state.detail,
|
|
238
|
-
runtime_status_updated_at: state.updatedAt,
|
|
239
|
-
active_turn_id: state.activeTurnId,
|
|
240
|
-
});
|
|
267
|
+
this.runtimeStateBySession.set(sessionKey, state);
|
|
241
268
|
}
|
|
242
269
|
setOutputMessage(sessionKey, messageId) {
|
|
243
|
-
|
|
270
|
+
if (messageId == null) {
|
|
271
|
+
this.outputMessageBySession.delete(sessionKey);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
this.outputMessageBySession.set(sessionKey, messageId);
|
|
244
275
|
}
|
|
245
276
|
setCwd(sessionKey, cwd) {
|
|
246
|
-
this.
|
|
277
|
+
this.patchDurableSession(sessionKey, { cwd });
|
|
247
278
|
}
|
|
248
279
|
setModel(sessionKey, model) {
|
|
249
|
-
this.
|
|
280
|
+
this.patchDurableSession(sessionKey, { model });
|
|
250
281
|
}
|
|
251
282
|
setSandboxMode(sessionKey, sandboxMode) {
|
|
252
|
-
this.
|
|
253
|
-
sandbox_mode: sandboxMode,
|
|
254
|
-
});
|
|
283
|
+
this.patchDurableSession(sessionKey, { sandboxMode });
|
|
255
284
|
}
|
|
256
285
|
setApprovalPolicy(sessionKey, approvalPolicy) {
|
|
257
|
-
this.
|
|
286
|
+
this.patchDurableSession(sessionKey, { approvalPolicy });
|
|
258
287
|
}
|
|
259
288
|
setReasoningEffort(sessionKey, reasoningEffort) {
|
|
260
|
-
this.
|
|
289
|
+
this.patchDurableSession(sessionKey, { reasoningEffort });
|
|
261
290
|
}
|
|
262
291
|
setWebSearchMode(sessionKey, webSearchMode) {
|
|
263
|
-
this.
|
|
292
|
+
this.patchDurableSession(sessionKey, { webSearchMode });
|
|
264
293
|
}
|
|
265
294
|
setNetworkAccessEnabled(sessionKey, enabled) {
|
|
266
|
-
this.
|
|
295
|
+
this.patchDurableSession(sessionKey, { networkAccessEnabled: enabled });
|
|
267
296
|
}
|
|
268
297
|
setSkipGitRepoCheck(sessionKey, skip) {
|
|
269
|
-
this.
|
|
298
|
+
this.patchDurableSession(sessionKey, { skipGitRepoCheck: skip });
|
|
270
299
|
}
|
|
271
300
|
setAdditionalDirectories(sessionKey, directories) {
|
|
272
|
-
this.
|
|
301
|
+
this.patchDurableSession(sessionKey, { additionalDirectories: [...directories] });
|
|
273
302
|
}
|
|
274
303
|
setOutputSchema(sessionKey, outputSchema) {
|
|
275
|
-
this.
|
|
304
|
+
this.patchDurableSession(sessionKey, { outputSchema });
|
|
276
305
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if (entries.length === 0)
|
|
280
|
-
return;
|
|
281
|
-
const setSql = entries.map(([key]) => `${key} = ?`).join(", ");
|
|
282
|
-
const values = entries.map(([, value]) => value);
|
|
283
|
-
values.push(new Date().toISOString(), sessionKey);
|
|
284
|
-
this.db.prepare(`UPDATE sessions SET ${setSql}, updated_at = ? WHERE session_key = ?`).run(...values);
|
|
306
|
+
patchDurableSession(sessionKey, patch) {
|
|
307
|
+
this.storage.patchSession(sessionKey, patch);
|
|
285
308
|
}
|
|
286
309
|
}
|
|
287
310
|
export function makeSessionKey(chatId, messageThreadId) {
|
|
288
311
|
return messageThreadId == null ? String(chatId) : `${chatId}:${messageThreadId}`;
|
|
289
312
|
}
|
|
290
|
-
function
|
|
313
|
+
function mapStoredSession(stored, runtimeState, outputMessageId) {
|
|
314
|
+
if (!stored)
|
|
315
|
+
return null;
|
|
316
|
+
const runtime = runtimeState ?? {
|
|
317
|
+
status: "idle",
|
|
318
|
+
detail: null,
|
|
319
|
+
updatedAt: stored.updatedAt,
|
|
320
|
+
activeTurnId: null,
|
|
321
|
+
};
|
|
291
322
|
return {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
sandboxMode: normalizeSandboxMode(row.sandbox_mode),
|
|
300
|
-
approvalPolicy: normalizeApprovalPolicy(row.approval_policy),
|
|
301
|
-
reasoningEffort: normalizeReasoningEffort(row.reasoning_effort),
|
|
302
|
-
webSearchMode: normalizeWebSearchMode(row.web_search_mode),
|
|
303
|
-
networkAccessEnabled: normalizeBoolean(row.network_access_enabled, true),
|
|
304
|
-
skipGitRepoCheck: normalizeBoolean(row.skip_git_repo_check, true),
|
|
305
|
-
additionalDirectories: normalizeStringArray(row.additional_directories),
|
|
306
|
-
outputSchema: normalizeOutputSchema(row.output_schema),
|
|
307
|
-
runtimeStatus: normalizeRuntimeStatus(row.runtime_status, row.active_turn_id),
|
|
308
|
-
runtimeStatusDetail: row.runtime_status_detail ?? null,
|
|
309
|
-
runtimeStatusUpdatedAt: row.runtime_status_updated_at ?? row.updated_at,
|
|
310
|
-
activeTurnId: row.active_turn_id,
|
|
311
|
-
outputMessageId: row.output_message_id,
|
|
312
|
-
createdAt: row.created_at,
|
|
313
|
-
updatedAt: row.updated_at,
|
|
323
|
+
...stored,
|
|
324
|
+
additionalDirectories: [...stored.additionalDirectories],
|
|
325
|
+
runtimeStatus: runtime.status,
|
|
326
|
+
runtimeStatusDetail: runtime.detail,
|
|
327
|
+
runtimeStatusUpdatedAt: runtime.updatedAt,
|
|
328
|
+
activeTurnId: runtime.activeTurnId,
|
|
329
|
+
outputMessageId: outputMessageId ?? null,
|
|
314
330
|
};
|
|
315
331
|
}
|
|
316
|
-
function
|
|
332
|
+
function cloneQueuedInput(input) {
|
|
317
333
|
return {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
text: row.text,
|
|
321
|
-
input: parseStoredCodexInput(row.input_json, row.text),
|
|
322
|
-
createdAt: row.created_at,
|
|
323
|
-
updatedAt: row.updated_at,
|
|
334
|
+
...input,
|
|
335
|
+
input: cloneStoredCodexInput(input.input),
|
|
324
336
|
};
|
|
325
337
|
}
|
|
326
|
-
function
|
|
327
|
-
return
|
|
328
|
-
}
|
|
329
|
-
function normalizeApprovalPolicy(value) {
|
|
330
|
-
return value && isSessionApprovalPolicy(value) ? value : DEFAULT_SESSION_PROFILE.approvalPolicy;
|
|
331
|
-
}
|
|
332
|
-
function normalizeReasoningEffort(value) {
|
|
333
|
-
return value && isSessionReasoningEffort(value) ? value : null;
|
|
334
|
-
}
|
|
335
|
-
function normalizeWebSearchMode(value) {
|
|
336
|
-
return value && isSessionWebSearchMode(value) ? value : null;
|
|
337
|
-
}
|
|
338
|
-
function normalizeBoolean(value, fallback) {
|
|
339
|
-
if (value == null)
|
|
340
|
-
return fallback;
|
|
341
|
-
return Number(value) !== 0;
|
|
342
|
-
}
|
|
343
|
-
function normalizeStringArray(value) {
|
|
344
|
-
if (!value)
|
|
345
|
-
return [];
|
|
346
|
-
try {
|
|
347
|
-
const parsed = JSON.parse(value);
|
|
348
|
-
if (!Array.isArray(parsed))
|
|
349
|
-
return [];
|
|
350
|
-
return parsed.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
351
|
-
}
|
|
352
|
-
catch {
|
|
353
|
-
return [];
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
function normalizeOutputSchema(value) {
|
|
357
|
-
if (!value?.trim())
|
|
358
|
-
return null;
|
|
359
|
-
try {
|
|
360
|
-
const parsed = JSON.parse(value);
|
|
361
|
-
return isPlainObject(parsed) ? JSON.stringify(parsed) : null;
|
|
362
|
-
}
|
|
363
|
-
catch {
|
|
364
|
-
return null;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
function normalizeRuntimeStatus(value, activeTurnId) {
|
|
368
|
-
switch (value) {
|
|
369
|
-
case "idle":
|
|
370
|
-
case "preparing":
|
|
371
|
-
case "running":
|
|
372
|
-
case "failed":
|
|
373
|
-
return value;
|
|
374
|
-
default:
|
|
375
|
-
return activeTurnId ? "running" : "idle";
|
|
376
|
-
}
|
|
338
|
+
function cloneStoredCodexInput(input) {
|
|
339
|
+
return typeof input === "string" ? input : input.map((item) => ({ ...item }));
|
|
377
340
|
}
|
|
378
341
|
function normalizeBindingCodeMode(value) {
|
|
379
342
|
return value === "rebind" ? "rebind" : "bootstrap";
|
|
@@ -390,44 +353,9 @@ function normalizeOptionalUserId(value) {
|
|
|
390
353
|
const parsed = Number(value);
|
|
391
354
|
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
392
355
|
}
|
|
393
|
-
function parseStoredCodexInput(inputJson, fallbackText) {
|
|
394
|
-
if (!inputJson)
|
|
395
|
-
return fallbackText;
|
|
396
|
-
try {
|
|
397
|
-
const parsed = JSON.parse(inputJson);
|
|
398
|
-
return normalizeStoredCodexInput(parsed) ?? fallbackText;
|
|
399
|
-
}
|
|
400
|
-
catch {
|
|
401
|
-
return fallbackText;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
function normalizeStoredCodexInput(value) {
|
|
405
|
-
if (typeof value === "string")
|
|
406
|
-
return value;
|
|
407
|
-
if (!Array.isArray(value))
|
|
408
|
-
return null;
|
|
409
|
-
const items = [];
|
|
410
|
-
for (const item of value) {
|
|
411
|
-
if (!isPlainObject(item))
|
|
412
|
-
return null;
|
|
413
|
-
if (item.type === "text" && typeof item.text === "string") {
|
|
414
|
-
items.push({ type: "text", text: item.text });
|
|
415
|
-
}
|
|
416
|
-
else if (item.type === "local_image" && typeof item.path === "string") {
|
|
417
|
-
items.push({ type: "local_image", path: item.path });
|
|
418
|
-
}
|
|
419
|
-
else {
|
|
420
|
-
return null;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
return items;
|
|
424
|
-
}
|
|
425
356
|
export function formatCodexInputPreview(input) {
|
|
426
357
|
if (typeof input === "string")
|
|
427
358
|
return input;
|
|
428
359
|
const parts = input.map((item) => (item.type === "text" ? item.text : `[image: ${item.path}]`));
|
|
429
360
|
return parts.join(" ").trim() || "[image]";
|
|
430
361
|
}
|
|
431
|
-
function isPlainObject(value) {
|
|
432
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
433
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "telecodex",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Telegram bridge for local Codex.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
43
|
"dev": "NODE_OPTIONS=--disable-warning=ExperimentalWarning tsx src/cli.ts",
|
|
44
|
-
"build": "tsc -p tsconfig.json",
|
|
44
|
+
"build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json",
|
|
45
45
|
"prepack": "npm run build",
|
|
46
46
|
"start": "node --disable-warning=ExperimentalWarning dist/cli.js",
|
|
47
47
|
"check": "tsc -p tsconfig.json --noEmit",
|