lark-remote 0.1.11 → 0.1.13
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/CHANGELOG.md +23 -0
- package/dist/bridge/inbound-media.d.ts +0 -3
- package/dist/bridge/inbound-media.js +0 -1
- package/dist/bridge/index.d.ts +7 -0
- package/dist/bridge/index.js +79 -70
- package/dist/card/card-shared.d.ts +1 -4
- package/dist/card/card-shared.js +2 -4
- package/dist/common/truncate.d.ts +0 -6
- package/dist/common/truncate.js +1 -1
- package/dist/common/ttl-cache.d.ts +24 -0
- package/dist/common/ttl-cache.js +53 -0
- package/dist/config/codex-config.d.ts +22 -0
- package/dist/config/codex-config.js +120 -25
- package/dist/config/index.d.ts +0 -3
- package/dist/config/index.js +0 -5
- package/dist/config/kimi-config.d.ts +1 -1
- package/dist/config/kimi-config.js +1 -1
- package/dist/config/opencode-config.d.ts +1 -1
- package/dist/config/opencode-config.js +3 -8
- package/dist/index.js +6 -0
- package/dist/router/index.d.ts +7 -0
- package/dist/router/index.js +229 -284
- package/dist/runner/claude/session.d.ts +0 -3
- package/dist/runner/claude/session.js +0 -5
- package/dist/runner/codex/app-server/runner.d.ts +1 -16
- package/dist/runner/codex/app-server/runner.js +2 -2
- package/dist/runner/common/acp/protocol-helpers.d.ts +31 -0
- package/dist/runner/common/acp/protocol-helpers.js +48 -0
- package/dist/runner/common/connection-based-runner.d.ts +0 -2
- package/dist/runner/common/connection-based-runner.js +1 -1
- package/dist/runner/dsh/index.d.ts +0 -2
- package/dist/runner/dsh/index.js +0 -2
- package/dist/runner/dsh/runner.d.ts +0 -2
- package/dist/runner/dsh/runner.js +1 -1
- package/dist/runner/index.d.ts +1 -1
- package/dist/runner/kimi/acp/runner.d.ts +18 -11
- package/dist/runner/kimi/acp/runner.js +95 -87
- package/dist/runner/kimi/acp/translator.d.ts +0 -1
- package/dist/runner/kimi/acp/translator.js +5 -13
- package/dist/runner/opencode/acp/error-monitor.d.ts +61 -0
- package/dist/runner/opencode/acp/error-monitor.js +150 -0
- package/dist/runner/opencode/acp/runner.d.ts +17 -0
- package/dist/runner/opencode/acp/runner.js +28 -42
- package/dist/runner/opencode/acp/translator.d.ts +0 -1
- package/dist/runner/opencode/acp/translator.js +3 -13
- package/dist/runner/pi/rpc/index.d.ts +0 -2
- package/dist/runner/pi/rpc/index.js +0 -2
- package/dist/runner/resolve-agent-choices.js +6 -2
- package/dist/runner/sync-agent-choices.js +1 -1
- package/dist/runner/types.d.ts +23 -0
- package/dist/session/claude/session-index.js +3 -1
- package/dist/session/claude/sessions.js +3 -7
- package/dist/session/codex/rollout-reader.d.ts +12 -2
- package/dist/session/codex/rollout-reader.js +259 -173
- package/dist/session/codex/sessions.d.ts +2 -1
- package/dist/session/codex/sessions.js +4 -1
- package/dist/session/common/pagination.d.ts +0 -2
- package/dist/session/common/pagination.js +1 -1
- package/dist/session/common/recency.d.ts +7 -0
- package/dist/session/common/recency.js +10 -0
- package/dist/session/common/usage-accumulator.d.ts +14 -0
- package/dist/session/common/usage-accumulator.js +15 -0
- package/dist/session/dsh/sessions.js +9 -6
- package/dist/session/kimi/sessions.d.ts +18 -4
- package/dist/session/kimi/sessions.js +49 -30
- package/dist/session/opencode/sessions.d.ts +2 -14
- package/dist/session/opencode/sessions.js +9 -7
- package/dist/session/pi/sessions.js +10 -22
- package/dist/update/index.d.ts +2 -2
- package/dist/update/index.js +1 -1
- package/package.json +1 -2
|
@@ -19,7 +19,9 @@ export interface KimiSessionState {
|
|
|
19
19
|
* `messagesCompacted` 是死字段,真实 record 里不存在——禁止再写。
|
|
20
20
|
*/
|
|
21
21
|
export interface KimiCompactionRecord {
|
|
22
|
-
type: 'full_compaction.complete' | 'context.apply_compaction';
|
|
22
|
+
type: 'full_compaction.begin' | 'full_compaction.complete' | 'full_compaction.cancel' | 'context.apply_compaction';
|
|
23
|
+
/** 压缩来源(仅 full_compaction.begin 携带):'manual' | 'auto'。 */
|
|
24
|
+
source?: string;
|
|
23
25
|
/** 压缩掉的消息条数(仅 context.apply_compaction 携带)。 */
|
|
24
26
|
compactedCount?: number;
|
|
25
27
|
/** 压缩前上下文 token 水位(仅 context.apply_compaction 携带)。 */
|
|
@@ -96,13 +98,25 @@ export declare class KimiSessionReader implements AgentSessionReader {
|
|
|
96
98
|
maxEvents?: number;
|
|
97
99
|
}): SessionContent;
|
|
98
100
|
/**
|
|
99
|
-
* Read the compaction records (
|
|
100
|
-
*
|
|
101
|
+
* Read the compaction records (full_compaction.begin / complete / cancel /
|
|
102
|
+
* context.apply_compaction) from a session's wire.jsonl.
|
|
101
103
|
*
|
|
102
104
|
* Same cwd guard as readSessionContent. Used by KimiAcpRunner.runCompact
|
|
103
|
-
*
|
|
105
|
+
* to wait for the background compaction terminal before ending the run, and
|
|
106
|
+
* by readCompactionState to detect an in-flight compaction.
|
|
104
107
|
*/
|
|
105
108
|
readCompactionRecords(sessionId: string, cwd: string): KimiCompactionRecord[];
|
|
109
|
+
/**
|
|
110
|
+
* 由 begin/terminal 记录重建压缩状态机:最后一次 begin 无更新的 terminal
|
|
111
|
+
* 记录 = 在途(kimi-compact-wait-redesign §5.1)。崩溃墓碑由 kimi resume
|
|
112
|
+
* 时补写 full_compaction.cancel,天然闭合。
|
|
113
|
+
*/
|
|
114
|
+
readCompactionState(sessionId: string, cwd: string): {
|
|
115
|
+
inFlight: boolean;
|
|
116
|
+
/** 在途 begin 的 time(epoch ms)。 */
|
|
117
|
+
inFlightSince?: number;
|
|
118
|
+
records: KimiCompactionRecord[];
|
|
119
|
+
};
|
|
106
120
|
/**
|
|
107
121
|
* Resolve the main wire.jsonl path for a session after passing the cwd
|
|
108
122
|
* guard (state.json + session index fallback). Returns null when the
|
|
@@ -2,10 +2,12 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import { readJsonlLines as readJsonlLinesShared, readLastNJsonlLines } from '../common/jsonl.js';
|
|
5
|
-
import { UsageAccumulator } from '../common/usage-accumulator.js';
|
|
5
|
+
import { UsageAccumulator, cumulativeUsageFields } from '../common/usage-accumulator.js';
|
|
6
6
|
import { getLogger } from '../../logger/index.js';
|
|
7
7
|
import { STALE_MS } from '../common/constants.js';
|
|
8
8
|
import { capEvents, paginate } from '../common/pagination.js';
|
|
9
|
+
import { sortByRecencyDesc } from '../common/recency.js';
|
|
10
|
+
import { TtlCache } from '../../common/ttl-cache.js';
|
|
9
11
|
import { truncateUtf8, TOOL_RESULT_MAX_BYTES } from '../../common/truncate.js';
|
|
10
12
|
import { truncateToolInput } from '../common/content-blocks.js';
|
|
11
13
|
/** Default Kimi config directory */
|
|
@@ -25,6 +27,16 @@ function isTurnPrompt(entry) {
|
|
|
25
27
|
function isCompactionComplete(entry) {
|
|
26
28
|
return entry.type === 'full_compaction.complete' || entry.type === 'context.apply_compaction';
|
|
27
29
|
}
|
|
30
|
+
/** full_compaction.begin:压缩开始(手动 /compact 或自动触发都写)。 */
|
|
31
|
+
function isCompactionBegin(entry) {
|
|
32
|
+
return entry.type === 'full_compaction.begin';
|
|
33
|
+
}
|
|
34
|
+
/** 压缩终态:完成(complete/apply)或失败/取消(cancel)共用 cancel 记录。 */
|
|
35
|
+
function isCompactionTerminal(entry) {
|
|
36
|
+
return (entry.type === 'full_compaction.complete' ||
|
|
37
|
+
entry.type === 'context.apply_compaction' ||
|
|
38
|
+
entry.type === 'full_compaction.cancel');
|
|
39
|
+
}
|
|
28
40
|
/**
|
|
29
41
|
* Max lines scanned backwards when looking for the last loop event.
|
|
30
42
|
* Bounds the tail scan so huge wire files are not fully parsed.
|
|
@@ -55,10 +67,7 @@ function lastLoopEventIsStepEnd(lines) {
|
|
|
55
67
|
return false;
|
|
56
68
|
}
|
|
57
69
|
/** Cache for JSONL file contents to avoid repeated full reads */
|
|
58
|
-
const jsonlCache = new
|
|
59
|
-
const CACHE_TTL_MS = 5000; // 5 second cache TTL
|
|
60
|
-
/** Upper bound on cached files; evict the least-recently-used entry past this. */
|
|
61
|
-
const CACHE_MAX_ENTRIES = 32;
|
|
70
|
+
const jsonlCache = new TtlCache(5_000, 32);
|
|
62
71
|
/**
|
|
63
72
|
* Read lines from a JSONL file with caching.
|
|
64
73
|
* Delegates to the shared readJsonlLines for the actual file read,
|
|
@@ -68,25 +77,14 @@ function readJsonlLines(filePath) {
|
|
|
68
77
|
try {
|
|
69
78
|
const stat = fs.statSync(filePath);
|
|
70
79
|
const mtime = stat.mtimeMs;
|
|
80
|
+
// P1-17: TTL 由 TtlCache 按缓存写入时间判定(不是文件 mtime),命中即 LRU 刷新;
|
|
81
|
+
// mtime 变化视为失效(文件被改写后不得返回旧行)。
|
|
71
82
|
const cached = jsonlCache.get(filePath);
|
|
72
|
-
|
|
73
|
-
// the FILE mtime — a file modified an hour ago would otherwise never hit
|
|
74
|
-
// the cache, making every call re-read and re-write the same entry.
|
|
75
|
-
if (cached && mtime === cached.mtime && Date.now() - cached.cachedAt < CACHE_TTL_MS) {
|
|
76
|
-
// LRU refresh on hit: re-insert so recently-used entries survive eviction.
|
|
77
|
-
jsonlCache.delete(filePath);
|
|
78
|
-
jsonlCache.set(filePath, cached);
|
|
83
|
+
if (cached && mtime === cached.mtime) {
|
|
79
84
|
return cached.lines;
|
|
80
85
|
}
|
|
81
86
|
const lines = readJsonlLinesShared(filePath);
|
|
82
|
-
jsonlCache.set(filePath, { mtime,
|
|
83
|
-
// P1-17: bound the cache. Map iteration is insertion order; after the LRU
|
|
84
|
-
// refresh above the least-recently-used entry is the first key.
|
|
85
|
-
if (jsonlCache.size > CACHE_MAX_ENTRIES) {
|
|
86
|
-
const oldest = jsonlCache.keys().next().value;
|
|
87
|
-
if (oldest !== undefined)
|
|
88
|
-
jsonlCache.delete(oldest);
|
|
89
|
-
}
|
|
87
|
+
jsonlCache.set(filePath, { mtime, lines });
|
|
90
88
|
return lines;
|
|
91
89
|
}
|
|
92
90
|
catch {
|
|
@@ -271,7 +269,7 @@ export class KimiSessionReader {
|
|
|
271
269
|
}
|
|
272
270
|
// Sort by mtime descending; same-mtime ties use a deterministic
|
|
273
271
|
// secondary key so ordering is stable across scans.
|
|
274
|
-
sessions
|
|
272
|
+
sortByRecencyDesc(sessions, (s) => s.mtime, (s) => s.sessionId);
|
|
275
273
|
const { items, total } = paginate(sessions, opts ?? {});
|
|
276
274
|
return {
|
|
277
275
|
sessions: items,
|
|
@@ -469,11 +467,7 @@ export class KimiSessionReader {
|
|
|
469
467
|
totalTokens: t.input + t.output + t.cacheRead + t.cacheCreation,
|
|
470
468
|
// Cumulative (session-wide): kimi sums all usage.records; mirrors
|
|
471
469
|
// inputTokens/outputTokens which are already session totals.
|
|
472
|
-
|
|
473
|
-
cumulativeInputTokens: t.input,
|
|
474
|
-
cumulativeOutputTokens: t.output,
|
|
475
|
-
cumulativeCacheReadTokens: t.cacheRead > 0 ? t.cacheRead : 0,
|
|
476
|
-
cumulativeCacheCreationTokens: t.cacheCreation > 0 ? t.cacheCreation : 0,
|
|
470
|
+
...cumulativeUsageFields(t),
|
|
477
471
|
// §6.3: compaction stats from wire.jsonl
|
|
478
472
|
compactCount,
|
|
479
473
|
...(compactPreContextLength !== undefined ? { compactPreContextLength } : {}),
|
|
@@ -490,11 +484,12 @@ export class KimiSessionReader {
|
|
|
490
484
|
}
|
|
491
485
|
}
|
|
492
486
|
/**
|
|
493
|
-
* Read the compaction records (
|
|
494
|
-
*
|
|
487
|
+
* Read the compaction records (full_compaction.begin / complete / cancel /
|
|
488
|
+
* context.apply_compaction) from a session's wire.jsonl.
|
|
495
489
|
*
|
|
496
490
|
* Same cwd guard as readSessionContent. Used by KimiAcpRunner.runCompact
|
|
497
|
-
*
|
|
491
|
+
* to wait for the background compaction terminal before ending the run, and
|
|
492
|
+
* by readCompactionState to detect an in-flight compaction.
|
|
498
493
|
*/
|
|
499
494
|
readCompactionRecords(sessionId, cwd) {
|
|
500
495
|
const wirePath = this.resolveSessionWirePath(sessionId, cwd);
|
|
@@ -506,9 +501,10 @@ export class KimiSessionReader {
|
|
|
506
501
|
for (const line of readJsonlLines(wirePath)) {
|
|
507
502
|
try {
|
|
508
503
|
const entry = JSON.parse(line);
|
|
509
|
-
if (
|
|
504
|
+
if (isCompactionBegin(entry) || isCompactionTerminal(entry)) {
|
|
510
505
|
records.push({
|
|
511
506
|
type: entry.type,
|
|
507
|
+
...(entry.source !== undefined ? { source: entry.source } : {}),
|
|
512
508
|
...(entry.compactedCount !== undefined
|
|
513
509
|
? { compactedCount: entry.compactedCount }
|
|
514
510
|
: {}),
|
|
@@ -529,6 +525,29 @@ export class KimiSessionReader {
|
|
|
529
525
|
}
|
|
530
526
|
return records;
|
|
531
527
|
}
|
|
528
|
+
/**
|
|
529
|
+
* 由 begin/terminal 记录重建压缩状态机:最后一次 begin 无更新的 terminal
|
|
530
|
+
* 记录 = 在途(kimi-compact-wait-redesign §5.1)。崩溃墓碑由 kimi resume
|
|
531
|
+
* 时补写 full_compaction.cancel,天然闭合。
|
|
532
|
+
*/
|
|
533
|
+
readCompactionState(sessionId, cwd) {
|
|
534
|
+
const records = [...this.readCompactionRecords(sessionId, cwd)].sort((a, b) => a.time - b.time);
|
|
535
|
+
let pendingBeginAt;
|
|
536
|
+
for (const record of records) {
|
|
537
|
+
if (isCompactionBegin(record)) {
|
|
538
|
+
pendingBeginAt = record.time;
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
// 终态(complete/apply/cancel)闭合当前在途压缩。
|
|
542
|
+
pendingBeginAt = undefined;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return {
|
|
546
|
+
inFlight: pendingBeginAt !== undefined,
|
|
547
|
+
...(pendingBeginAt !== undefined ? { inFlightSince: pendingBeginAt } : {}),
|
|
548
|
+
records,
|
|
549
|
+
};
|
|
550
|
+
}
|
|
532
551
|
/**
|
|
533
552
|
* Resolve the main wire.jsonl path for a session after passing the cwd
|
|
534
553
|
* guard (state.json + session index fallback). Returns null when the
|
|
@@ -24,25 +24,13 @@ interface OpencodeSessionReaderOptions {
|
|
|
24
24
|
*/
|
|
25
25
|
captureExport?: (sessionId: string) => string;
|
|
26
26
|
}
|
|
27
|
-
interface OpencodeSessionListEntry {
|
|
28
|
-
id: string;
|
|
29
|
-
title: string;
|
|
30
|
-
updated: number;
|
|
31
|
-
created: number;
|
|
32
|
-
projectId: string;
|
|
33
|
-
directory: string;
|
|
34
|
-
}
|
|
35
27
|
export declare class OpencodeSessionReader implements AgentSessionReader {
|
|
36
28
|
private readonly binary;
|
|
37
29
|
private readonly cacheTtlMs;
|
|
38
30
|
/** Optional raw-export capture override (testing / alt transport). */
|
|
39
31
|
private readonly captureExportOverride?;
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
listCache: Map<string, {
|
|
43
|
-
ts: number;
|
|
44
|
-
data: OpencodeSessionListEntry[];
|
|
45
|
-
}>;
|
|
32
|
+
/** cwd → 列表缓存(TTL 由 cacheTtlMs 决定)。 */
|
|
33
|
+
private listCache;
|
|
46
34
|
constructor(opts?: OpencodeSessionReaderOptions);
|
|
47
35
|
/**
|
|
48
36
|
* List sessions in a given cwd, using directory field for matching.
|
|
@@ -22,17 +22,19 @@ import { truncateUtf8, TOOL_RESULT_MAX_BYTES } from '../../common/truncate.js';
|
|
|
22
22
|
import { getLogger } from '../../logger/index.js';
|
|
23
23
|
import { STALE_MS } from '../common/constants.js';
|
|
24
24
|
import { paginate, capEvents } from '../common/pagination.js';
|
|
25
|
+
import { sortByRecencyDesc } from '../common/recency.js';
|
|
26
|
+
import { TtlCache } from '../../common/ttl-cache.js';
|
|
25
27
|
export class OpencodeSessionReader {
|
|
26
28
|
binary;
|
|
27
29
|
cacheTtlMs;
|
|
28
30
|
/** Optional raw-export capture override (testing / alt transport). */
|
|
29
31
|
captureExportOverride;
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
listCache = new Map();
|
|
32
|
+
/** cwd → 列表缓存(TTL 由 cacheTtlMs 决定)。 */
|
|
33
|
+
listCache;
|
|
33
34
|
constructor(opts = {}) {
|
|
34
35
|
this.binary = 'opencode';
|
|
35
36
|
this.cacheTtlMs = opts.cacheTtlMs ?? 10_000;
|
|
37
|
+
this.listCache = new TtlCache(this.cacheTtlMs);
|
|
36
38
|
this.captureExportOverride = opts.captureExport;
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
@@ -47,7 +49,7 @@ export class OpencodeSessionReader {
|
|
|
47
49
|
const filtered = entries.filter((e) => e.directory === realCwd);
|
|
48
50
|
// Sort by updated descending; same-updated ties use id as a deterministic
|
|
49
51
|
// secondary key so CLI/list-cache rebuilds never reorder the page.
|
|
50
|
-
filtered
|
|
52
|
+
sortByRecencyDesc(filtered, (s) => s.updated, (s) => s.id);
|
|
51
53
|
// Compute total over the full sorted set, then paginate.
|
|
52
54
|
const { items, total } = paginate(filtered, opts ?? {});
|
|
53
55
|
return {
|
|
@@ -302,8 +304,8 @@ export class OpencodeSessionReader {
|
|
|
302
304
|
fetchSessionList(cwd) {
|
|
303
305
|
const realCwd = this.realpath(cwd);
|
|
304
306
|
const cached = this.listCache.get(realCwd);
|
|
305
|
-
if (cached
|
|
306
|
-
return cached
|
|
307
|
+
if (cached) {
|
|
308
|
+
return cached;
|
|
307
309
|
}
|
|
308
310
|
try {
|
|
309
311
|
// Pass cwd to execFileSync so opencode CLI returns sessions for the correct directory
|
|
@@ -322,7 +324,7 @@ export class OpencodeSessionReader {
|
|
|
322
324
|
}
|
|
323
325
|
const data = JSON.parse(output);
|
|
324
326
|
// Update cache keyed by cwd
|
|
325
|
-
this.listCache.set(realCwd,
|
|
327
|
+
this.listCache.set(realCwd, data);
|
|
326
328
|
return data;
|
|
327
329
|
}
|
|
328
330
|
catch (err) {
|
|
@@ -3,9 +3,11 @@ import path from 'node:path';
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import { findJsonlLine, scanJsonlLines, readJsonlLinesFromOffset } from '../common/jsonl.js';
|
|
5
5
|
import { extractContentBlocks } from '../common/content-blocks.js';
|
|
6
|
-
import { UsageAccumulator } from '../common/usage-accumulator.js';
|
|
6
|
+
import { UsageAccumulator, contextWindowOccupancy, cumulativeUsageFields, } from '../common/usage-accumulator.js';
|
|
7
7
|
import { STALE_MS } from '../common/constants.js';
|
|
8
8
|
import { capEvents, paginate } from '../common/pagination.js';
|
|
9
|
+
import { sortByRecencyDesc } from '../common/recency.js';
|
|
10
|
+
import { TtlCache } from '../../common/ttl-cache.js';
|
|
9
11
|
function defaultPiDir() {
|
|
10
12
|
return path.join(os.homedir(), '.pi', 'agent');
|
|
11
13
|
}
|
|
@@ -19,10 +21,7 @@ function projectDirForCwd(cwd, sessionsDir) {
|
|
|
19
21
|
* P1-19: TTL cache for pi directory scans (mirror codex getSessionIndex's
|
|
20
22
|
* 5s TTL). Repeated /resume pages re-scan the whole sessions dir per call.
|
|
21
23
|
*/
|
|
22
|
-
const
|
|
23
|
-
/** Upper bound on cached listings; FIFO eviction past this. */
|
|
24
|
-
const PI_LIST_MAX_ENTRIES = 32;
|
|
25
|
-
const piListCache = new Map();
|
|
24
|
+
const piListCache = new TtlCache(5_000, 32);
|
|
26
25
|
/** Pi-specific field-name mapping for content block extraction. */
|
|
27
26
|
export const PI_MAPPING = {
|
|
28
27
|
toolUseType: 'toolCall',
|
|
@@ -207,21 +206,16 @@ function buildPiUsage(acc) {
|
|
|
207
206
|
return undefined;
|
|
208
207
|
}
|
|
209
208
|
const l = acc.last;
|
|
210
|
-
const contextLength = l.input + l.cacheRead + l.cacheCreation;
|
|
211
209
|
return {
|
|
212
210
|
inputTokens: l.input,
|
|
213
211
|
outputTokens: l.output,
|
|
214
|
-
contextLength,
|
|
212
|
+
contextLength: contextWindowOccupancy(l),
|
|
215
213
|
compactCount: acc.compactCount > 0 ? acc.compactCount : undefined,
|
|
216
214
|
cacheReadTokens: l.cacheRead > 0 ? l.cacheRead : 0,
|
|
217
215
|
cacheCreationTokens: l.cacheCreation > 0 ? l.cacheCreation : 0,
|
|
218
216
|
totalTokens: l.total > 0 ? l.total : undefined,
|
|
219
217
|
// Cumulative (session-wide): sum of ALL runs in the jsonl file.
|
|
220
|
-
|
|
221
|
-
cumulativeInputTokens: t.input,
|
|
222
|
-
cumulativeOutputTokens: t.output,
|
|
223
|
-
cumulativeCacheReadTokens: t.cacheRead,
|
|
224
|
-
cumulativeCacheCreationTokens: t.cacheCreation,
|
|
218
|
+
...cumulativeUsageFields(t),
|
|
225
219
|
};
|
|
226
220
|
}
|
|
227
221
|
/**
|
|
@@ -346,8 +340,8 @@ export class PiSessionReader {
|
|
|
346
340
|
listSessionsByScan(cwd) {
|
|
347
341
|
const cacheKey = `${this.sessionsDir}\u0000${cwd}`;
|
|
348
342
|
const cached = piListCache.get(cacheKey);
|
|
349
|
-
if (cached
|
|
350
|
-
return cached
|
|
343
|
+
if (cached) {
|
|
344
|
+
return cached;
|
|
351
345
|
}
|
|
352
346
|
const dir = projectDirForCwd(cwd, this.sessionsDir);
|
|
353
347
|
let files;
|
|
@@ -381,14 +375,8 @@ export class PiSessionReader {
|
|
|
381
375
|
}
|
|
382
376
|
}
|
|
383
377
|
// Same-mtime ties: secondary key keeps the full order deterministic.
|
|
384
|
-
sessions
|
|
385
|
-
piListCache.set(cacheKey,
|
|
386
|
-
// Bound the cache (map iteration order = insertion order).
|
|
387
|
-
if (piListCache.size > PI_LIST_MAX_ENTRIES) {
|
|
388
|
-
const oldest = piListCache.keys().next().value;
|
|
389
|
-
if (oldest !== undefined)
|
|
390
|
-
piListCache.delete(oldest);
|
|
391
|
-
}
|
|
378
|
+
sortByRecencyDesc(sessions, (s) => s.mtime, (s) => s.sessionId);
|
|
379
|
+
piListCache.set(cacheKey, sessions);
|
|
392
380
|
return sessions;
|
|
393
381
|
}
|
|
394
382
|
}
|
package/dist/update/index.d.ts
CHANGED
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* package installation (detect package manager + global install),
|
|
6
6
|
* and the combined workflow for the /update command and --update CLI flag.
|
|
7
7
|
*/
|
|
8
|
-
export { isNewer, checkLatestVersion, type VersionCheckResult
|
|
9
|
-
export { runInstallLatest, type
|
|
8
|
+
export { isNewer, checkLatestVersion, type VersionCheckResult } from './version-check.js';
|
|
9
|
+
export { runInstallLatest, type InstallResult } from './install.js';
|
|
10
10
|
export { formatUpdateHint } from './startup-hint.js';
|
package/dist/update/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* package installation (detect package manager + global install),
|
|
6
6
|
* and the combined workflow for the /update command and --update CLI flag.
|
|
7
7
|
*/
|
|
8
|
-
export { isNewer, checkLatestVersion
|
|
8
|
+
export { isNewer, checkLatestVersion } from './version-check.js';
|
|
9
9
|
export { runInstallLatest } from './install.js';
|
|
10
10
|
export { formatUpdateHint } from './startup-hint.js';
|
|
11
11
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lark-remote",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "Feishu (Lark) private-chat bridge to local coding agents — Claude Code / Codex / opencode / pi / kimi, with live-streaming CardKit 2.0 cards",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -101,7 +101,6 @@
|
|
|
101
101
|
},
|
|
102
102
|
"devDependencies": {
|
|
103
103
|
"@eslint/js": "^10.0.1",
|
|
104
|
-
"@types/form-data": "^2.5.2",
|
|
105
104
|
"@types/node": "^26.1.2",
|
|
106
105
|
"@types/qrcode-terminal": "^0.12.2",
|
|
107
106
|
"@vitest/coverage-v8": "4.1.10",
|