@sideboard-ai/core 0.1.208 → 0.1.210
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/dist/{abletime-I4IYZBKU.js → abletime-GDZLZRMY.js} +4 -4
- package/dist/{abletime-UWSSLXH3.js → abletime-QGGYL2G4.js} +4 -4
- package/dist/{abletime-oauth-C3BQXKW3.js → abletime-oauth-3X3BAPTF.js} +3 -3
- package/dist/{abletime-oauth-UZHPB3W2.js → abletime-oauth-F335TWKY.js} +3 -3
- package/dist/{abletime-rest-HYNYDYK3.js → abletime-rest-LAGTPAJL.js} +3 -3
- package/dist/{abletime-rest-5YPPEOKK.js → abletime-rest-PLJVY3H3.js} +3 -3
- package/dist/agents/cursor-runner.js +3 -3
- package/dist/{agents-QHQXR55O.js → agents-G3TFVFBQ.js} +6 -5
- package/dist/{agents-CCS5IEBV.js → agents-IQZUN47D.js} +6 -5
- package/dist/{app-settings-GJ6KDYEF.js → app-settings-2TN3WLZV.js} +7 -1
- package/dist/{app-settings-R2KNCT37.js → app-settings-XCRNCEEE.js} +7 -1
- package/dist/{chunk-F4LZUEIO.js → chunk-2M5B7YNY.js} +2 -2
- package/dist/{chunk-C6ZNQV5W.js → chunk-2R6BZRRB.js} +117 -25
- package/dist/{chunk-HA4EZKFY.js → chunk-3S2LDD2F.js} +3 -3
- package/dist/{chunk-6YZLSZLK.js → chunk-42IULNIY.js} +3 -3
- package/dist/{chunk-C5MNMITQ.js → chunk-AOQZZA3M.js} +119 -25
- package/dist/{chunk-4EGK47WV.js → chunk-BTC2D6LS.js} +217 -0
- package/dist/{chunk-7DKX5JLT.js → chunk-FGTPRMPS.js} +18 -3
- package/dist/{chunk-X45BV4VX.js → chunk-G4TANQC3.js} +5 -5
- package/dist/{chunk-Y4CF7LHH.js → chunk-L5CIEBLR.js} +232 -0
- package/dist/{chunk-WXWJ5MJ4.js → chunk-LS6TSOCE.js} +5 -5
- package/dist/{chunk-6J4OQ6TF.js → chunk-MN6YUD4O.js} +3 -3
- package/dist/{chunk-7PEIIN7P.js → chunk-NDE5RKZP.js} +24 -87
- package/dist/{chunk-W6X4GZJG.js → chunk-REZRGCKV.js} +3 -3
- package/dist/{chunk-NJ2CCLV6.js → chunk-WX4S775K.js} +2 -2
- package/dist/chunk-X5B3OS5I.js +34 -0
- package/dist/{chunk-ZHCB4CKR.js → chunk-X5PUFYDJ.js} +18 -3
- package/dist/{chunk-TEDEVD4O.js → chunk-YVE4PXCJ.js} +2 -2
- package/dist/{chunk-A6SOSLUV.js → chunk-YYELAUKP.js} +24 -94
- package/dist/{chunk-DNTPX6HV.js → chunk-ZC664YBJ.js} +3 -3
- package/dist/{chunk-OP6CFVTB.js → chunk-ZZNZX2QW.js} +2 -2
- package/dist/{coordinator-prompt-WOTJQMD5.js → coordinator-prompt-GCITY3Q5.js} +5 -4
- package/dist/{coordinator-prompt-TUHB6ZFA.js → coordinator-prompt-PONGPWIP.js} +5 -4
- package/dist/{cursor-recover-TXVTLAMA.js → cursor-recover-4PQAADAU.js} +3 -28
- package/dist/{global-workspace-V6G2KH2V.js → global-workspace-LIZHU4GM.js} +5 -4
- package/dist/{global-workspace-5UUUNA4A.js → global-workspace-LQZLTGFL.js} +5 -4
- package/dist/index.cjs +681 -385
- package/dist/index.d.cts +96 -5
- package/dist/index.d.ts +96 -5
- package/dist/index.js +52 -19
- package/dist/mcp/run-stdio.cjs +647 -385
- package/dist/mcp/run-stdio.js +12 -11
- package/dist/{orchestrator-4IGHVRAF.js → orchestrator-G5HELCVT.js} +7 -6
- package/dist/{orchestrator-D4AQNF25.js → orchestrator-ZBUXJCII.js} +7 -6
- package/dist/{thread-store-FMWDFAO5.js → thread-store-FCWU7Y3X.js} +2 -1
- package/dist/{thread-store-ESZYZSVC.js → thread-store-KMZRQEPY.js} +2 -1
- package/dist/{workspaces-PZ36M7EQ.js → workspaces-2XW2DMRG.js} +5 -4
- package/dist/{workspaces-CLNANACI.js → workspaces-T6PMQZYQ.js} +5 -4
- package/dist/{worktree-JKTM47K5.js → worktree-2OEMMFRT.js} +4 -3
- package/dist/{worktree-NC4XQNQI.js → worktree-5ZGWKKZ6.js} +4 -3
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
getAbleTimeHost,
|
|
6
6
|
isAbleTimeConnected
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-L5CIEBLR.js";
|
|
8
8
|
|
|
9
9
|
// src/integrations/abletime-mcp.ts
|
|
10
10
|
var DEFAULT_ABLETIME_HOST = "https://track.abletime.com";
|
|
@@ -153,7 +153,7 @@ function textsFromUnknown(value) {
|
|
|
153
153
|
return "";
|
|
154
154
|
}
|
|
155
155
|
async function abletimeMcpRequest(method, params, opts) {
|
|
156
|
-
const rawToken = opts?.token ?? await import("./abletime-oauth-
|
|
156
|
+
const rawToken = opts?.token ?? await import("./abletime-oauth-3X3BAPTF.js").then((m) => m.ensureAbleTimeAccessToken());
|
|
157
157
|
if (!rawToken?.trim()) {
|
|
158
158
|
throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
|
|
159
159
|
}
|
|
@@ -224,9 +224,9 @@ async function callAbleTimeTool(name, args = {}, opts) {
|
|
|
224
224
|
if (!opts?.token && !isAbleTimeConnected()) {
|
|
225
225
|
throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
|
|
226
226
|
}
|
|
227
|
-
const rawToken = opts?.token ?? await import("./abletime-oauth-
|
|
227
|
+
const rawToken = opts?.token ?? await import("./abletime-oauth-3X3BAPTF.js").then((m) => m.ensureAbleTimeAccessToken());
|
|
228
228
|
if (rawToken && ableTimeUsesRest(rawToken)) {
|
|
229
|
-
const { callAbleTimeRestTool } = await import("./abletime-rest-
|
|
229
|
+
const { callAbleTimeRestTool } = await import("./abletime-rest-PLJVY3H3.js");
|
|
230
230
|
return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
|
|
231
231
|
}
|
|
232
232
|
const requestOpts = { ...opts, pm: opts?.pm ?? abletimeToolUsesPm(name) };
|
|
@@ -242,7 +242,7 @@ async function callAbleTimeTool(name, args = {}, opts) {
|
|
|
242
242
|
return await call();
|
|
243
243
|
}
|
|
244
244
|
if (rawToken && ableTimeUsesRest(rawToken) && isAbleTimeRejectedCredential(message)) {
|
|
245
|
-
const { callAbleTimeRestTool } = await import("./abletime-rest-
|
|
245
|
+
const { callAbleTimeRestTool } = await import("./abletime-rest-PLJVY3H3.js");
|
|
246
246
|
return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
|
|
247
247
|
}
|
|
248
248
|
throw err instanceof Error ? new Error(rewriteAbleTimeError(err.message)) : err;
|
|
@@ -355,6 +355,170 @@ function normalizeVault(raw) {
|
|
|
355
355
|
return out;
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
+
// src/agents/usage.ts
|
|
359
|
+
function sumOptional(a, b) {
|
|
360
|
+
if (a == null && b == null) return void 0;
|
|
361
|
+
return (a ?? 0) + (b ?? 0);
|
|
362
|
+
}
|
|
363
|
+
function fromInclusiveInputUsage(opts) {
|
|
364
|
+
const totalInput = Number(opts.inputTokens) || 0;
|
|
365
|
+
const outputTokens = Number(opts.outputTokens) || 0;
|
|
366
|
+
const cached = Number(opts.cachedInputTokens) || 0;
|
|
367
|
+
if (!totalInput && !outputTokens) return null;
|
|
368
|
+
const cacheReadTokens = cached > 0 ? Math.min(cached, totalInput) : 0;
|
|
369
|
+
return {
|
|
370
|
+
inputTokens: Math.max(0, totalInput - cacheReadTokens),
|
|
371
|
+
outputTokens,
|
|
372
|
+
cacheReadTokens: cacheReadTokens || void 0
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
function requestOccupancy(u) {
|
|
376
|
+
return u.inputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
|
|
377
|
+
}
|
|
378
|
+
function mergeUsage(a, b) {
|
|
379
|
+
return {
|
|
380
|
+
inputTokens: (a?.inputTokens ?? 0) + b.inputTokens,
|
|
381
|
+
outputTokens: (a?.outputTokens ?? 0) + b.outputTokens,
|
|
382
|
+
cacheReadTokens: sumOptional(a?.cacheReadTokens, b.cacheReadTokens),
|
|
383
|
+
cacheWriteTokens: sumOptional(a?.cacheWriteTokens, b.cacheWriteTokens),
|
|
384
|
+
costUsd: sumOptional(a?.costUsd, b.costUsd),
|
|
385
|
+
lastRequestTokens: b.lastRequestTokens ?? a?.lastRequestTokens
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function sumUsageList(list) {
|
|
389
|
+
let acc = null;
|
|
390
|
+
for (const u of list) {
|
|
391
|
+
if (!u) continue;
|
|
392
|
+
acc = mergeUsage(acc, {
|
|
393
|
+
inputTokens: u.inputTokens,
|
|
394
|
+
outputTokens: u.outputTokens,
|
|
395
|
+
cacheReadTokens: u.cacheReadTokens,
|
|
396
|
+
cacheWriteTokens: u.cacheWriteTokens,
|
|
397
|
+
costUsd: u.costUsd
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
if (!acc) return null;
|
|
401
|
+
return {
|
|
402
|
+
inputTokens: acc.inputTokens,
|
|
403
|
+
outputTokens: acc.outputTokens,
|
|
404
|
+
...acc.cacheReadTokens != null ? { cacheReadTokens: acc.cacheReadTokens } : {},
|
|
405
|
+
...acc.cacheWriteTokens != null ? { cacheWriteTokens: acc.cacheWriteTokens } : {},
|
|
406
|
+
...acc.costUsd != null ? { costUsd: acc.costUsd } : {}
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
function hasBilledTokens(u) {
|
|
410
|
+
return Boolean(
|
|
411
|
+
u.inputTokens || u.outputTokens || u.cacheReadTokens || u.cacheWriteTokens
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
function applyTurnUsage(current, incoming, scope = "request") {
|
|
415
|
+
if (scope === "turn") {
|
|
416
|
+
if (!hasBilledTokens(incoming) && current && incoming.costUsd != null) {
|
|
417
|
+
return { ...current, costUsd: incoming.costUsd };
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
...incoming,
|
|
421
|
+
costUsd: incoming.costUsd ?? current?.costUsd,
|
|
422
|
+
lastRequestTokens: current?.lastRequestTokens ?? requestOccupancy(incoming)
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
const merged = mergeUsage(current, incoming);
|
|
426
|
+
const occ = incoming.lastRequestTokens != null && incoming.lastRequestTokens > 0 ? incoming.lastRequestTokens : requestOccupancy(incoming);
|
|
427
|
+
return {
|
|
428
|
+
...merged,
|
|
429
|
+
lastRequestTokens: occ > 0 ? occ : current?.lastRequestTokens ?? occ
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
function totalTokens(u) {
|
|
433
|
+
return u.inputTokens + u.outputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
|
|
434
|
+
}
|
|
435
|
+
function contextTokens(u) {
|
|
436
|
+
if (u.lastRequestTokens != null && u.lastRequestTokens > 0) return u.lastRequestTokens;
|
|
437
|
+
return requestOccupancy(u);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// src/store/history-retention.ts
|
|
441
|
+
var HISTORY_MAX_COUNT_DEFAULT = 200;
|
|
442
|
+
var HISTORY_MAX_COUNT_MIN = 1;
|
|
443
|
+
var HISTORY_MAX_COUNT_MAX = 2e3;
|
|
444
|
+
var HISTORY_MAX_DAYS_DEFAULT = 0;
|
|
445
|
+
var HISTORY_MAX_DAYS_MAX = 3650;
|
|
446
|
+
var HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT = 6;
|
|
447
|
+
var HISTORY_DISCARDED_TEXT = "Transcript discarded by History retention.";
|
|
448
|
+
function clampHistoryMaxCount(value) {
|
|
449
|
+
return Math.max(HISTORY_MAX_COUNT_MIN, Math.min(HISTORY_MAX_COUNT_MAX, Math.floor(value)));
|
|
450
|
+
}
|
|
451
|
+
function clampHistoryMaxDays(value) {
|
|
452
|
+
if (!Number.isFinite(value) || value <= 0) return 0;
|
|
453
|
+
return Math.min(HISTORY_MAX_DAYS_MAX, Math.floor(value));
|
|
454
|
+
}
|
|
455
|
+
function archivedUpdatedMs(thread) {
|
|
456
|
+
const stamped = thread.archivedAt ? Date.parse(thread.archivedAt) : NaN;
|
|
457
|
+
if (Number.isFinite(stamped)) return stamped;
|
|
458
|
+
const updated = Date.parse(thread.updatedAt);
|
|
459
|
+
if (Number.isFinite(updated)) return updated;
|
|
460
|
+
const created = Date.parse(thread.createdAt);
|
|
461
|
+
return Number.isFinite(created) ? created : 0;
|
|
462
|
+
}
|
|
463
|
+
function isHistoryRetentionStub(thread) {
|
|
464
|
+
if ((thread.attachments?.length ?? 0) > 0) return false;
|
|
465
|
+
const messages = thread.messages ?? [];
|
|
466
|
+
if (messages.length === 0) return true;
|
|
467
|
+
if (messages.length > 1) return false;
|
|
468
|
+
const only = messages[0];
|
|
469
|
+
if (only.parts?.length) return false;
|
|
470
|
+
if ((only.attachments?.length ?? 0) > 0) return false;
|
|
471
|
+
const text = (only.text ?? "").trim();
|
|
472
|
+
return text === "" || text === HISTORY_DISCARDED_TEXT;
|
|
473
|
+
}
|
|
474
|
+
function historyRetentionStubMessage(thread) {
|
|
475
|
+
const usage = sumUsageList((thread.messages ?? []).map((m) => m.usage));
|
|
476
|
+
return {
|
|
477
|
+
role: "summary",
|
|
478
|
+
text: HISTORY_DISCARDED_TEXT,
|
|
479
|
+
ts: thread.updatedAt,
|
|
480
|
+
...usage ? { usage } : {}
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
function sortArchivedOldestFirst(threads) {
|
|
484
|
+
return [...threads].sort((a, b) => archivedUpdatedMs(a) - archivedUpdatedMs(b));
|
|
485
|
+
}
|
|
486
|
+
function planHistoryRetention(archived, thresholds = {}) {
|
|
487
|
+
const maxCount = clampHistoryMaxCount(thresholds.maxCount ?? HISTORY_MAX_COUNT_DEFAULT);
|
|
488
|
+
const maxDays = clampHistoryMaxDays(thresholds.maxDays ?? HISTORY_MAX_DAYS_DEFAULT);
|
|
489
|
+
const nowMs = thresholds.nowMs ?? Date.now();
|
|
490
|
+
const oldestFirst = sortArchivedOldestFirst(archived);
|
|
491
|
+
const expiredIds = /* @__PURE__ */ new Set();
|
|
492
|
+
if (maxDays > 0) {
|
|
493
|
+
const cutoff = nowMs - maxDays * 864e5;
|
|
494
|
+
for (const thread of oldestFirst) {
|
|
495
|
+
if (archivedUpdatedMs(thread) < cutoff) expiredIds.add(thread.id);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
const remaining = oldestFirst.filter((t) => !expiredIds.has(t.id));
|
|
499
|
+
const overflow = remaining.length > maxCount ? remaining.slice(0, remaining.length - maxCount) : [];
|
|
500
|
+
const stripIds = [];
|
|
501
|
+
const purgeIds = [...expiredIds];
|
|
502
|
+
const seenPurge = new Set(purgeIds);
|
|
503
|
+
for (const thread of overflow) {
|
|
504
|
+
if (isHistoryRetentionStub(thread)) {
|
|
505
|
+
if (!seenPurge.has(thread.id)) {
|
|
506
|
+
seenPurge.add(thread.id);
|
|
507
|
+
purgeIds.push(thread.id);
|
|
508
|
+
}
|
|
509
|
+
} else {
|
|
510
|
+
stripIds.push(thread.id);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return { stripIds, purgeIds };
|
|
514
|
+
}
|
|
515
|
+
function planHistoryAgePurge(archived, olderThanDays, nowMs = Date.now()) {
|
|
516
|
+
const days = clampHistoryMaxDays(olderThanDays);
|
|
517
|
+
if (days <= 0) return [];
|
|
518
|
+
const cutoff = nowMs - days * 864e5;
|
|
519
|
+
return sortArchivedOldestFirst(archived).filter((t) => archivedUpdatedMs(t) < cutoff).map((t) => t.id);
|
|
520
|
+
}
|
|
521
|
+
|
|
358
522
|
// src/store/usage-on-limit.ts
|
|
359
523
|
var USAGE_ON_LIMIT_VALUES = [
|
|
360
524
|
"keep_going",
|
|
@@ -815,6 +979,24 @@ function normalizeAdvanced(raw) {
|
|
|
815
979
|
if (typeof source.autoCleanupOrphans === "boolean") {
|
|
816
980
|
out.autoCleanupOrphans = source.autoCleanupOrphans;
|
|
817
981
|
}
|
|
982
|
+
if (typeof source.autoCleanupHistory === "boolean") {
|
|
983
|
+
out.autoCleanupHistory = source.autoCleanupHistory;
|
|
984
|
+
}
|
|
985
|
+
if (typeof source.historyMaxCount === "number" && Number.isFinite(source.historyMaxCount)) {
|
|
986
|
+
out.historyMaxCount = clampHistoryMaxCount(source.historyMaxCount);
|
|
987
|
+
}
|
|
988
|
+
if (typeof source.historyMaxDays === "number" && Number.isFinite(source.historyMaxDays)) {
|
|
989
|
+
out.historyMaxDays = clampHistoryMaxDays(source.historyMaxDays);
|
|
990
|
+
}
|
|
991
|
+
if (typeof source.historyCleanupIntervalHours === "number" && Number.isFinite(source.historyCleanupIntervalHours)) {
|
|
992
|
+
out.historyCleanupIntervalHours = Math.max(
|
|
993
|
+
1,
|
|
994
|
+
Math.min(168, Math.floor(source.historyCleanupIntervalHours))
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
if (typeof source.historyLastCleanupAt === "string" && source.historyLastCleanupAt.trim()) {
|
|
998
|
+
out.historyLastCleanupAt = source.historyLastCleanupAt.trim();
|
|
999
|
+
}
|
|
818
1000
|
if (source.orchestrationQuotaOnLimit === "switch_agent" || source.orchestrationQuotaOnLimit === "wait_reset") {
|
|
819
1001
|
out.orchestrationQuotaOnLimit = source.orchestrationQuotaOnLimit;
|
|
820
1002
|
}
|
|
@@ -1720,6 +1902,24 @@ function updateAdvancedSettings(patch) {
|
|
|
1720
1902
|
if (typeof patch.autoCleanupOrphans === "boolean") {
|
|
1721
1903
|
advanced.autoCleanupOrphans = patch.autoCleanupOrphans;
|
|
1722
1904
|
}
|
|
1905
|
+
if (typeof patch.autoCleanupHistory === "boolean") {
|
|
1906
|
+
advanced.autoCleanupHistory = patch.autoCleanupHistory;
|
|
1907
|
+
}
|
|
1908
|
+
if (typeof patch.historyMaxCount === "number" && Number.isFinite(patch.historyMaxCount)) {
|
|
1909
|
+
advanced.historyMaxCount = clampHistoryMaxCount(patch.historyMaxCount);
|
|
1910
|
+
}
|
|
1911
|
+
if (typeof patch.historyMaxDays === "number" && Number.isFinite(patch.historyMaxDays)) {
|
|
1912
|
+
advanced.historyMaxDays = clampHistoryMaxDays(patch.historyMaxDays);
|
|
1913
|
+
}
|
|
1914
|
+
if (typeof patch.historyCleanupIntervalHours === "number" && Number.isFinite(patch.historyCleanupIntervalHours)) {
|
|
1915
|
+
advanced.historyCleanupIntervalHours = Math.max(
|
|
1916
|
+
1,
|
|
1917
|
+
Math.min(168, Math.floor(patch.historyCleanupIntervalHours))
|
|
1918
|
+
);
|
|
1919
|
+
}
|
|
1920
|
+
if (typeof patch.historyLastCleanupAt === "string") {
|
|
1921
|
+
advanced.historyLastCleanupAt = patch.historyLastCleanupAt;
|
|
1922
|
+
}
|
|
1723
1923
|
if (patch.orchestrationQuotaOnLimit === "switch_agent" || patch.orchestrationQuotaOnLimit === "wait_reset") {
|
|
1724
1924
|
advanced.orchestrationQuotaOnLimit = patch.orchestrationQuotaOnLimit;
|
|
1725
1925
|
}
|
|
@@ -1770,6 +1970,15 @@ function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
|
|
|
1770
1970
|
function autoCleanupOrphansEnabled(settings = loadAppSettings()) {
|
|
1771
1971
|
return Boolean(settings.advanced.autoCleanupOrphans);
|
|
1772
1972
|
}
|
|
1973
|
+
function autoCleanupHistoryEnabled(settings = loadAppSettings()) {
|
|
1974
|
+
return settings.advanced.autoCleanupHistory !== false;
|
|
1975
|
+
}
|
|
1976
|
+
function historyMaxCount(settings = loadAppSettings()) {
|
|
1977
|
+
return clampHistoryMaxCount(settings.advanced.historyMaxCount ?? HISTORY_MAX_COUNT_DEFAULT);
|
|
1978
|
+
}
|
|
1979
|
+
function historyMaxDays(settings = loadAppSettings()) {
|
|
1980
|
+
return clampHistoryMaxDays(settings.advanced.historyMaxDays ?? HISTORY_MAX_DAYS_DEFAULT);
|
|
1981
|
+
}
|
|
1773
1982
|
function usageOnLimit(settings = loadAppSettings()) {
|
|
1774
1983
|
return resolveUsageOnLimit(settings.advanced);
|
|
1775
1984
|
}
|
|
@@ -1903,6 +2112,26 @@ export {
|
|
|
1903
2112
|
writeSecureJson,
|
|
1904
2113
|
isSecureFileEncrypted,
|
|
1905
2114
|
secureFileUnlocksWith,
|
|
2115
|
+
fromInclusiveInputUsage,
|
|
2116
|
+
requestOccupancy,
|
|
2117
|
+
mergeUsage,
|
|
2118
|
+
sumUsageList,
|
|
2119
|
+
applyTurnUsage,
|
|
2120
|
+
totalTokens,
|
|
2121
|
+
contextTokens,
|
|
2122
|
+
HISTORY_MAX_COUNT_DEFAULT,
|
|
2123
|
+
HISTORY_MAX_COUNT_MIN,
|
|
2124
|
+
HISTORY_MAX_COUNT_MAX,
|
|
2125
|
+
HISTORY_MAX_DAYS_DEFAULT,
|
|
2126
|
+
HISTORY_MAX_DAYS_MAX,
|
|
2127
|
+
HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT,
|
|
2128
|
+
HISTORY_DISCARDED_TEXT,
|
|
2129
|
+
clampHistoryMaxCount,
|
|
2130
|
+
clampHistoryMaxDays,
|
|
2131
|
+
isHistoryRetentionStub,
|
|
2132
|
+
historyRetentionStubMessage,
|
|
2133
|
+
planHistoryRetention,
|
|
2134
|
+
planHistoryAgePurge,
|
|
1906
2135
|
USAGE_ON_LIMIT_VALUES,
|
|
1907
2136
|
isUsageOnLimit,
|
|
1908
2137
|
resolveUsageOnLimit,
|
|
@@ -1972,6 +2201,9 @@ export {
|
|
|
1972
2201
|
confirmClaudeUsageOverLimitEnabled,
|
|
1973
2202
|
autoArchiveOnMergeEnabled,
|
|
1974
2203
|
autoCleanupOrphansEnabled,
|
|
2204
|
+
autoCleanupHistoryEnabled,
|
|
2205
|
+
historyMaxCount,
|
|
2206
|
+
historyMaxDays,
|
|
1975
2207
|
usageOnLimit,
|
|
1976
2208
|
orchestrationQuotaOnLimit,
|
|
1977
2209
|
orchestrationQuotaFallbackAgent,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
getAbleTimeHost,
|
|
8
8
|
isAbleTimeConnected
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BTC2D6LS.js";
|
|
10
10
|
|
|
11
11
|
// src/integrations/abletime-mcp.ts
|
|
12
12
|
var DEFAULT_ABLETIME_HOST = "https://track.abletime.com";
|
|
@@ -155,7 +155,7 @@ function textsFromUnknown(value) {
|
|
|
155
155
|
return "";
|
|
156
156
|
}
|
|
157
157
|
async function abletimeMcpRequest(method, params, opts) {
|
|
158
|
-
const rawToken = opts?.token ?? await import("./abletime-oauth-
|
|
158
|
+
const rawToken = opts?.token ?? await import("./abletime-oauth-F335TWKY.js").then((m) => m.ensureAbleTimeAccessToken());
|
|
159
159
|
if (!rawToken?.trim()) {
|
|
160
160
|
throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
|
|
161
161
|
}
|
|
@@ -226,9 +226,9 @@ async function callAbleTimeTool(name, args = {}, opts) {
|
|
|
226
226
|
if (!opts?.token && !isAbleTimeConnected()) {
|
|
227
227
|
throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
|
|
228
228
|
}
|
|
229
|
-
const rawToken = opts?.token ?? await import("./abletime-oauth-
|
|
229
|
+
const rawToken = opts?.token ?? await import("./abletime-oauth-F335TWKY.js").then((m) => m.ensureAbleTimeAccessToken());
|
|
230
230
|
if (rawToken && ableTimeUsesRest(rawToken)) {
|
|
231
|
-
const { callAbleTimeRestTool } = await import("./abletime-rest-
|
|
231
|
+
const { callAbleTimeRestTool } = await import("./abletime-rest-LAGTPAJL.js");
|
|
232
232
|
return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
|
|
233
233
|
}
|
|
234
234
|
const requestOpts = { ...opts, pm: opts?.pm ?? abletimeToolUsesPm(name) };
|
|
@@ -244,7 +244,7 @@ async function callAbleTimeTool(name, args = {}, opts) {
|
|
|
244
244
|
return await call();
|
|
245
245
|
}
|
|
246
246
|
if (rawToken && ableTimeUsesRest(rawToken) && isAbleTimeRejectedCredential(message)) {
|
|
247
|
-
const { callAbleTimeRestTool } = await import("./abletime-rest-
|
|
247
|
+
const { callAbleTimeRestTool } = await import("./abletime-rest-LAGTPAJL.js");
|
|
248
248
|
return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
|
|
249
249
|
}
|
|
250
250
|
throw err instanceof Error ? new Error(rewriteAbleTimeError(err.message)) : err;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_ABLETIME_HOST,
|
|
3
3
|
normalizeAbleTimeHost
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-G4TANQC3.js";
|
|
5
5
|
import {
|
|
6
6
|
httpFetch
|
|
7
7
|
} from "./chunk-N7WZ6NIN.js";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
getAbleTimeHost,
|
|
11
11
|
loadAppSettings,
|
|
12
12
|
saveAbleTimeConnection
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-L5CIEBLR.js";
|
|
14
14
|
|
|
15
15
|
// src/integrations/abletime-oauth.ts
|
|
16
16
|
import { createHash, randomBytes } from "crypto";
|
|
@@ -280,7 +280,7 @@ async function startAbleTimeOAuth(opts) {
|
|
|
280
280
|
persistAbleTimeTokens(data, { host });
|
|
281
281
|
const token = data.access_token.trim();
|
|
282
282
|
try {
|
|
283
|
-
const { getAbleTimeOrientation } = await import("./abletime-
|
|
283
|
+
const { getAbleTimeOrientation } = await import("./abletime-GDZLZRMY.js");
|
|
284
284
|
const orientation = await getAbleTimeOrientation({ token, host });
|
|
285
285
|
return saveAbleTimeConnection({
|
|
286
286
|
accessToken: token,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
isOrchestratorThread
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ZC664YBJ.js";
|
|
6
6
|
import {
|
|
7
7
|
applyConnectedTeamToCli,
|
|
8
8
|
brightsyMcpServerName,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
mergeAgentGitAuthEnv,
|
|
21
21
|
resolveAgentGitAuthEnv,
|
|
22
22
|
resolveCodexGitWritableRoots
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-WX4S775K.js";
|
|
24
24
|
import {
|
|
25
25
|
enrichPathWithNpmGlobalBin,
|
|
26
26
|
isConductorBundledCli,
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
} from "./chunk-FNQNJOHY.js";
|
|
31
31
|
import {
|
|
32
32
|
claudeChromeEnabled,
|
|
33
|
+
fromInclusiveInputUsage,
|
|
33
34
|
isAbleTimeConnected,
|
|
34
35
|
isElectronLikeCommand,
|
|
35
36
|
isLinearConnected,
|
|
@@ -38,7 +39,7 @@ import {
|
|
|
38
39
|
resolveClaudeExecutable,
|
|
39
40
|
unwrapStrippedElectronLaunch,
|
|
40
41
|
wrapElectronAsNodeLaunch
|
|
41
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-BTC2D6LS.js";
|
|
42
43
|
import {
|
|
43
44
|
appDataDir
|
|
44
45
|
} from "./chunk-EQNRWDLN.js";
|
|
@@ -46,85 +47,6 @@ import {
|
|
|
46
47
|
// src/agents/brightsy.ts
|
|
47
48
|
import { existsSync } from "fs";
|
|
48
49
|
|
|
49
|
-
// src/agents/usage.ts
|
|
50
|
-
function sumOptional(a, b) {
|
|
51
|
-
if (a == null && b == null) return void 0;
|
|
52
|
-
return (a ?? 0) + (b ?? 0);
|
|
53
|
-
}
|
|
54
|
-
function fromInclusiveInputUsage(opts) {
|
|
55
|
-
const totalInput = Number(opts.inputTokens) || 0;
|
|
56
|
-
const outputTokens = Number(opts.outputTokens) || 0;
|
|
57
|
-
const cached = Number(opts.cachedInputTokens) || 0;
|
|
58
|
-
if (!totalInput && !outputTokens) return null;
|
|
59
|
-
const cacheReadTokens = cached > 0 ? Math.min(cached, totalInput) : 0;
|
|
60
|
-
return {
|
|
61
|
-
inputTokens: Math.max(0, totalInput - cacheReadTokens),
|
|
62
|
-
outputTokens,
|
|
63
|
-
cacheReadTokens: cacheReadTokens || void 0
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
function requestOccupancy(u) {
|
|
67
|
-
return u.inputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
|
|
68
|
-
}
|
|
69
|
-
function mergeUsage(a, b) {
|
|
70
|
-
return {
|
|
71
|
-
inputTokens: (a?.inputTokens ?? 0) + b.inputTokens,
|
|
72
|
-
outputTokens: (a?.outputTokens ?? 0) + b.outputTokens,
|
|
73
|
-
cacheReadTokens: sumOptional(a?.cacheReadTokens, b.cacheReadTokens),
|
|
74
|
-
cacheWriteTokens: sumOptional(a?.cacheWriteTokens, b.cacheWriteTokens),
|
|
75
|
-
costUsd: sumOptional(a?.costUsd, b.costUsd),
|
|
76
|
-
lastRequestTokens: b.lastRequestTokens ?? a?.lastRequestTokens
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function sumUsageList(list) {
|
|
80
|
-
let acc = null;
|
|
81
|
-
for (const u of list) {
|
|
82
|
-
if (!u) continue;
|
|
83
|
-
acc = mergeUsage(acc, {
|
|
84
|
-
inputTokens: u.inputTokens,
|
|
85
|
-
outputTokens: u.outputTokens,
|
|
86
|
-
cacheReadTokens: u.cacheReadTokens,
|
|
87
|
-
cacheWriteTokens: u.cacheWriteTokens,
|
|
88
|
-
costUsd: u.costUsd
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
if (!acc) return null;
|
|
92
|
-
return {
|
|
93
|
-
inputTokens: acc.inputTokens,
|
|
94
|
-
outputTokens: acc.outputTokens,
|
|
95
|
-
...acc.cacheReadTokens != null ? { cacheReadTokens: acc.cacheReadTokens } : {},
|
|
96
|
-
...acc.cacheWriteTokens != null ? { cacheWriteTokens: acc.cacheWriteTokens } : {},
|
|
97
|
-
...acc.costUsd != null ? { costUsd: acc.costUsd } : {}
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
function hasBilledTokens(u) {
|
|
101
|
-
return Boolean(
|
|
102
|
-
u.inputTokens || u.outputTokens || u.cacheReadTokens || u.cacheWriteTokens
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
function applyTurnUsage(current, incoming, scope = "request") {
|
|
106
|
-
if (scope === "turn") {
|
|
107
|
-
if (!hasBilledTokens(incoming) && current && incoming.costUsd != null) {
|
|
108
|
-
return { ...current, costUsd: incoming.costUsd };
|
|
109
|
-
}
|
|
110
|
-
return {
|
|
111
|
-
...incoming,
|
|
112
|
-
costUsd: incoming.costUsd ?? current?.costUsd,
|
|
113
|
-
lastRequestTokens: current?.lastRequestTokens ?? requestOccupancy(incoming)
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
const merged = mergeUsage(current, incoming);
|
|
117
|
-
const occ = incoming.lastRequestTokens != null && incoming.lastRequestTokens > 0 ? incoming.lastRequestTokens : requestOccupancy(incoming);
|
|
118
|
-
return {
|
|
119
|
-
...merged,
|
|
120
|
-
lastRequestTokens: occ > 0 ? occ : current?.lastRequestTokens ?? occ
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
function contextTokens(u) {
|
|
124
|
-
if (u.lastRequestTokens != null && u.lastRequestTokens > 0) return u.lastRequestTokens;
|
|
125
|
-
return requestOccupancy(u);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
50
|
// src/agents/brightsy-targets.ts
|
|
129
51
|
function encodeBrightsyTarget(type, id, accountId) {
|
|
130
52
|
if (accountId) return `team:${accountId}:${type}:${id}`;
|
|
@@ -2299,13 +2221,31 @@ function mcpStatusThinkingFromClaudeInit(obj) {
|
|
|
2299
2221
|
}
|
|
2300
2222
|
}
|
|
2301
2223
|
}
|
|
2302
|
-
const notable = servers.filter(
|
|
2224
|
+
const notable = servers.filter(isNotableMcpInitStatus);
|
|
2303
2225
|
if (notable.length === 0) return null;
|
|
2304
2226
|
return `MCP: ${notable.map((s) => `${s.name} ${s.status}`).join(", ")}`;
|
|
2305
2227
|
}
|
|
2306
2228
|
function isCleanMcpConnect(status) {
|
|
2307
2229
|
return /^(connected|ok|ready|success)$/i.test(status.trim());
|
|
2308
2230
|
}
|
|
2231
|
+
function isMcpAuthStatus(status) {
|
|
2232
|
+
return /needs[_-]?auth|needs authentication|unauthorized|not authenticated|authrequired/i.test(
|
|
2233
|
+
status
|
|
2234
|
+
);
|
|
2235
|
+
}
|
|
2236
|
+
function isSideboardMcpName(name) {
|
|
2237
|
+
return /^sideboard$/i.test(name.trim()) || /^mcp__sideboard$/i.test(name.trim());
|
|
2238
|
+
}
|
|
2239
|
+
function isVendorClaudeAiMcpName(name) {
|
|
2240
|
+
return /^claude\.ai\b/i.test(name.trim()) || /^mcp__claude_ai_/i.test(name.trim());
|
|
2241
|
+
}
|
|
2242
|
+
function isNotableMcpInitStatus(server) {
|
|
2243
|
+
if (isCleanMcpConnect(server.status)) return false;
|
|
2244
|
+
if (isSideboardMcpName(server.name)) return true;
|
|
2245
|
+
if (isVendorClaudeAiMcpName(server.name)) return false;
|
|
2246
|
+
if (isMcpAuthStatus(server.status)) return false;
|
|
2247
|
+
return true;
|
|
2248
|
+
}
|
|
2309
2249
|
function eventsFromClaudeSystem(obj) {
|
|
2310
2250
|
const subtype = claudeString(obj, "subtype") ?? "";
|
|
2311
2251
|
const parentId = claudeParentToolUseId(obj);
|
|
@@ -2474,7 +2414,7 @@ var claudeAdapter = {
|
|
|
2474
2414
|
);
|
|
2475
2415
|
}
|
|
2476
2416
|
const mode = permissionMode(thread);
|
|
2477
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
2417
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-LIZHU4GM.js");
|
|
2478
2418
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
2479
2419
|
const injectedServers = await buildInjectedMcpServers({
|
|
2480
2420
|
includeSideboard: true,
|
|
@@ -4809,9 +4749,6 @@ export {
|
|
|
4809
4749
|
shouldFeedErrorBackToAgent,
|
|
4810
4750
|
formatAgentErrorContinuePrompt,
|
|
4811
4751
|
formatTurnExitError,
|
|
4812
|
-
sumUsageList,
|
|
4813
|
-
applyTurnUsage,
|
|
4814
|
-
contextTokens,
|
|
4815
4752
|
encodeBrightsyTarget,
|
|
4816
4753
|
decodeBrightsyTarget,
|
|
4817
4754
|
parseBrightsyCliLine,
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
textFromAbleTimeDoc
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2M5B7YNY.js";
|
|
4
4
|
import {
|
|
5
5
|
assertAbleTimeCredential,
|
|
6
6
|
callAbleTimeTool,
|
|
7
7
|
normalizeAbleTimeHost,
|
|
8
8
|
rewriteAbleTimeError
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-G4TANQC3.js";
|
|
10
10
|
import {
|
|
11
11
|
isAbleTimeConnected,
|
|
12
12
|
saveAbleTimeConnection
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-L5CIEBLR.js";
|
|
14
14
|
|
|
15
15
|
// src/integrations/abletime.ts
|
|
16
16
|
var CLOSED_STATES = /* @__PURE__ */ new Set([
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-D6JWYJ4P.js";
|
|
6
6
|
import {
|
|
7
7
|
listThreads
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-X5PUFYDJ.js";
|
|
9
9
|
import {
|
|
10
10
|
ensureWorktreeSideboardIgnored
|
|
11
11
|
} from "./chunk-SYFVUF2C.js";
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
import {
|
|
23
23
|
getGithubGitAuthMode,
|
|
24
24
|
getGithubPat
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-BTC2D6LS.js";
|
|
26
26
|
import {
|
|
27
27
|
worktreesRoot
|
|
28
28
|
} from "./chunk-EQNRWDLN.js";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
appDataDir
|
|
5
|
+
} from "./chunk-EQNRWDLN.js";
|
|
6
|
+
|
|
7
|
+
// src/agents/cursor-store.ts
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
var CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
|
|
10
|
+
function cursorSdkStoreDir(threadId) {
|
|
11
|
+
const root = join(appDataDir(), CURSOR_SDK_STORE_DIR);
|
|
12
|
+
const id = sanitizeCursorStoreSegment(threadId);
|
|
13
|
+
if (!id) return root;
|
|
14
|
+
return join(root, "threads", id);
|
|
15
|
+
}
|
|
16
|
+
function cursorSdkRunsNdjsonPath(threadId) {
|
|
17
|
+
return join(cursorSdkStoreDir(threadId), "runs.ndjson");
|
|
18
|
+
}
|
|
19
|
+
function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
20
|
+
const scoped = cursorSdkRunsNdjsonPath(threadId);
|
|
21
|
+
const shared = cursorSdkRunsNdjsonPath(null);
|
|
22
|
+
if (!threadId || !sanitizeCursorStoreSegment(threadId) || scoped === shared) {
|
|
23
|
+
return [shared];
|
|
24
|
+
}
|
|
25
|
+
return [scoped, shared];
|
|
26
|
+
}
|
|
27
|
+
function sanitizeCursorStoreSegment(threadId) {
|
|
28
|
+
return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
cursorSdkStoreDir,
|
|
33
|
+
cursorSdkRunsNdjsonSearchPaths
|
|
34
|
+
};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
cursorSdkStoreDir
|
|
5
|
+
} from "./chunk-X5B3OS5I.js";
|
|
3
6
|
import {
|
|
4
7
|
normalizeThinkingEffort
|
|
5
8
|
} from "./chunk-KGZBYWZ3.js";
|
|
@@ -15,6 +18,7 @@ import {
|
|
|
15
18
|
existsSync,
|
|
16
19
|
readFileSync,
|
|
17
20
|
renameSync,
|
|
21
|
+
rmSync,
|
|
18
22
|
statSync,
|
|
19
23
|
unlinkSync,
|
|
20
24
|
writeFileSync,
|
|
@@ -54,7 +58,8 @@ function normalizeThread(raw) {
|
|
|
54
58
|
userSetTitle: Boolean(raw.userSetTitle),
|
|
55
59
|
activeRuns: Array.isArray(raw.activeRuns) ? raw.activeRuns : [],
|
|
56
60
|
quotaResumeAt: raw.quotaResumeAt ?? null,
|
|
57
|
-
quotaContinuedFromId: raw.quotaContinuedFromId ?? null
|
|
61
|
+
quotaContinuedFromId: raw.quotaContinuedFromId ?? null,
|
|
62
|
+
archivedAt: typeof raw.archivedAt === "string" && raw.archivedAt.trim() ? raw.archivedAt.trim() : void 0
|
|
58
63
|
};
|
|
59
64
|
}
|
|
60
65
|
function createEmptyThread(partial) {
|
|
@@ -89,6 +94,7 @@ function createEmptyThread(partial) {
|
|
|
89
94
|
pendingTurnAttachments: partial.pendingTurnAttachments ?? [],
|
|
90
95
|
createdAt: ts,
|
|
91
96
|
updatedAt: ts,
|
|
97
|
+
archivedAt: typeof partial.archivedAt === "string" && partial.archivedAt.trim() ? partial.archivedAt.trim() : void 0,
|
|
92
98
|
title: partial.title,
|
|
93
99
|
sourceType: partial.sourceType,
|
|
94
100
|
sourceRef: partial.sourceRef,
|
|
@@ -161,10 +167,10 @@ function readThread(id) {
|
|
|
161
167
|
rememberThread(thread, mtimeMs);
|
|
162
168
|
return thread;
|
|
163
169
|
}
|
|
164
|
-
function writeThread(thread) {
|
|
170
|
+
function writeThread(thread, opts) {
|
|
165
171
|
const path = threadFilePath(idPath(thread.id));
|
|
166
172
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
167
|
-
const next = { ...thread, updatedAt: nowIso() };
|
|
173
|
+
const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
|
|
168
174
|
writeFileSync(tmp, JSON.stringify(next, null, 2), "utf8");
|
|
169
175
|
renameSync(tmp, path);
|
|
170
176
|
rememberThread(next, fileMtimeMs(path) ?? Date.now());
|
|
@@ -209,11 +215,20 @@ function deleteThreadRecord(id) {
|
|
|
209
215
|
} catch {
|
|
210
216
|
}
|
|
211
217
|
}
|
|
218
|
+
try {
|
|
219
|
+
rmSync(cursorSdkStoreDir(id), { recursive: true, force: true });
|
|
220
|
+
} catch {
|
|
221
|
+
}
|
|
212
222
|
}
|
|
213
223
|
function updateThread(id, patch) {
|
|
214
224
|
const current = readThread(id);
|
|
215
225
|
if (!current) throw new Error(`Thread not found: ${id}`);
|
|
216
226
|
const next = { ...current, ...patch, id: current.id, updatedAt: nowIso() };
|
|
227
|
+
if (next.status === "archived") {
|
|
228
|
+
next.archivedAt = typeof next.archivedAt === "string" && next.archivedAt.trim() || current.archivedAt || nowIso();
|
|
229
|
+
} else {
|
|
230
|
+
delete next.archivedAt;
|
|
231
|
+
}
|
|
217
232
|
writeThread(next);
|
|
218
233
|
return next;
|
|
219
234
|
}
|