clawprobe 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +301 -0
- package/dist/cli/commands/compacts.d.ts +11 -0
- package/dist/cli/commands/compacts.d.ts.map +1 -0
- package/dist/cli/commands/compacts.js +68 -0
- package/dist/cli/commands/compacts.js.map +1 -0
- package/dist/cli/commands/context.d.ts +8 -0
- package/dist/cli/commands/context.d.ts.map +1 -0
- package/dist/cli/commands/context.js +78 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/cost.d.ts +12 -0
- package/dist/cli/commands/cost.d.ts.map +1 -0
- package/dist/cli/commands/cost.js +52 -0
- package/dist/cli/commands/cost.js.map +1 -0
- package/dist/cli/commands/memory.d.ts +36 -0
- package/dist/cli/commands/memory.d.ts.map +1 -0
- package/dist/cli/commands/memory.js +139 -0
- package/dist/cli/commands/memory.js.map +1 -0
- package/dist/cli/commands/session.d.ts +10 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +95 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/status.d.ts +9 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +68 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/suggest.d.ts +11 -0
- package/dist/cli/commands/suggest.d.ts.map +1 -0
- package/dist/cli/commands/suggest.js +68 -0
- package/dist/cli/commands/suggest.js.map +1 -0
- package/dist/cli/format.d.ts +29 -0
- package/dist/cli/format.d.ts.map +1 -0
- package/dist/cli/format.js +125 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/core/config.d.ts +63 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +92 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/db.d.ts +87 -0
- package/dist/core/db.d.ts.map +1 -0
- package/dist/core/db.js +263 -0
- package/dist/core/db.js.map +1 -0
- package/dist/core/jsonl-parser.d.ts +55 -0
- package/dist/core/jsonl-parser.d.ts.map +1 -0
- package/dist/core/jsonl-parser.js +79 -0
- package/dist/core/jsonl-parser.js.map +1 -0
- package/dist/core/memory-editor.d.ts +18 -0
- package/dist/core/memory-editor.d.ts.map +1 -0
- package/dist/core/memory-editor.js +125 -0
- package/dist/core/memory-editor.js.map +1 -0
- package/dist/core/session-store.d.ts +35 -0
- package/dist/core/session-store.d.ts.map +1 -0
- package/dist/core/session-store.js +66 -0
- package/dist/core/session-store.js.map +1 -0
- package/dist/core/watcher.d.ts +19 -0
- package/dist/core/watcher.d.ts.map +1 -0
- package/dist/core/watcher.js +83 -0
- package/dist/core/watcher.js.map +1 -0
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +147 -0
- package/dist/daemon.js.map +1 -0
- package/dist/engines/compact-diff.d.ts +19 -0
- package/dist/engines/compact-diff.d.ts.map +1 -0
- package/dist/engines/compact-diff.js +124 -0
- package/dist/engines/compact-diff.js.map +1 -0
- package/dist/engines/cost.d.ts +73 -0
- package/dist/engines/cost.d.ts.map +1 -0
- package/dist/engines/cost.js +149 -0
- package/dist/engines/cost.js.map +1 -0
- package/dist/engines/file-analyzer.d.ts +28 -0
- package/dist/engines/file-analyzer.d.ts.map +1 -0
- package/dist/engines/file-analyzer.js +139 -0
- package/dist/engines/file-analyzer.js.map +1 -0
- package/dist/engines/rule-engine.d.ts +25 -0
- package/dist/engines/rule-engine.d.ts.map +1 -0
- package/dist/engines/rule-engine.js +209 -0
- package/dist/engines/rule-engine.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +207 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export interface OpenClawCompactionConfig {
|
|
2
|
+
reserveTokens?: number;
|
|
3
|
+
keepRecentTokens?: number;
|
|
4
|
+
}
|
|
5
|
+
export interface OpenClawConfig {
|
|
6
|
+
agents?: {
|
|
7
|
+
defaults?: {
|
|
8
|
+
workspace?: string;
|
|
9
|
+
bootstrapMaxChars?: number;
|
|
10
|
+
compaction?: OpenClawCompactionConfig;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
plugins?: {
|
|
14
|
+
slots?: {
|
|
15
|
+
contextEngine?: string;
|
|
16
|
+
memory?: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
models?: {
|
|
20
|
+
default?: string;
|
|
21
|
+
provider?: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface ProbeConfig {
|
|
25
|
+
openclaw: {
|
|
26
|
+
dir: string;
|
|
27
|
+
agent: string;
|
|
28
|
+
};
|
|
29
|
+
server: {
|
|
30
|
+
port: number;
|
|
31
|
+
host: string;
|
|
32
|
+
};
|
|
33
|
+
cost: {
|
|
34
|
+
customPrices: Record<string, {
|
|
35
|
+
input: number;
|
|
36
|
+
output: number;
|
|
37
|
+
}>;
|
|
38
|
+
};
|
|
39
|
+
alerts: {
|
|
40
|
+
dailyBudgetUsd?: number;
|
|
41
|
+
weeklyBudgetUsd?: number;
|
|
42
|
+
};
|
|
43
|
+
memory: {
|
|
44
|
+
defaultFile: string;
|
|
45
|
+
};
|
|
46
|
+
rules: {
|
|
47
|
+
disabled: string[];
|
|
48
|
+
compactionFreqThresholdMin: number;
|
|
49
|
+
memoryBloatThresholdChars: number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export interface ResolvedConfig {
|
|
53
|
+
probe: ProbeConfig;
|
|
54
|
+
openclaw: OpenClawConfig;
|
|
55
|
+
openclawDir: string;
|
|
56
|
+
workspaceDir: string;
|
|
57
|
+
sessionsDir: string;
|
|
58
|
+
bootstrapMaxChars: number;
|
|
59
|
+
probeDir: string;
|
|
60
|
+
}
|
|
61
|
+
export declare function resolveConfig(overrides?: Partial<ProbeConfig>): ResolvedConfig;
|
|
62
|
+
export declare function assertOpenClawExists(cfg: ResolvedConfig): void;
|
|
63
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,wBAAwB;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE;YACT,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;YAC3B,UAAU,CAAC,EAAE,wBAAwB,CAAC;SACvC,CAAC;KACH,CAAC;IACF,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE;YACN,aAAa,CAAC,EAAE,MAAM,CAAC;YACvB,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC;KACH,CAAC;IACF,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE;QACR,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,IAAI,EAAE;QACJ,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACjE,CAAC;IACF,MAAM,EAAE;QACN,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,MAAM,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,0BAA0B,EAAE,MAAM,CAAC;QACnC,yBAAyB,EAAE,MAAM,CAAC;KACnC,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAyBD,wBAAgB,aAAa,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,cAAc,CAuDlF;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAQ9D"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import os from "os";
|
|
4
|
+
const DEFAULT_PROBE_CONFIG = {
|
|
5
|
+
openclaw: {
|
|
6
|
+
dir: path.join(os.homedir(), ".openclaw"),
|
|
7
|
+
agent: "main",
|
|
8
|
+
},
|
|
9
|
+
server: {
|
|
10
|
+
port: 4747,
|
|
11
|
+
host: "127.0.0.1",
|
|
12
|
+
},
|
|
13
|
+
cost: {
|
|
14
|
+
customPrices: {},
|
|
15
|
+
},
|
|
16
|
+
alerts: {},
|
|
17
|
+
memory: {
|
|
18
|
+
defaultFile: "MEMORY.md",
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
disabled: [],
|
|
22
|
+
compactionFreqThresholdMin: 30,
|
|
23
|
+
memoryBloatThresholdChars: 50000,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export function resolveConfig(overrides = {}) {
|
|
27
|
+
const probeDir = path.join(os.homedir(), ".clawprobe");
|
|
28
|
+
const probeConfigPath = path.join(probeDir, "config.json");
|
|
29
|
+
let fileConfig = {};
|
|
30
|
+
if (fs.existsSync(probeConfigPath)) {
|
|
31
|
+
try {
|
|
32
|
+
fileConfig = JSON.parse(fs.readFileSync(probeConfigPath, "utf-8"));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// ignore malformed config
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const probe = deepMerge(DEFAULT_PROBE_CONFIG, fileConfig, overrides);
|
|
39
|
+
// OPENCLAW_DIR env var takes priority
|
|
40
|
+
const openclawDir = process.env["OPENCLAW_DIR"] ?? probe.openclaw.dir;
|
|
41
|
+
const openclawConfigPath = path.join(openclawDir, "openclaw.json");
|
|
42
|
+
let openclawConfig = {};
|
|
43
|
+
if (fs.existsSync(openclawConfigPath)) {
|
|
44
|
+
try {
|
|
45
|
+
openclawConfig = JSON.parse(fs.readFileSync(openclawConfigPath, "utf-8"));
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// ignore malformed config
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const workspaceDir = openclawConfig.agents?.defaults?.workspace ??
|
|
52
|
+
path.join(openclawDir, "workspace");
|
|
53
|
+
const sessionsDir = path.join(openclawDir, "agents", probe.openclaw.agent, "sessions");
|
|
54
|
+
const bootstrapMaxChars = openclawConfig.agents?.defaults?.bootstrapMaxChars ?? 20000;
|
|
55
|
+
return {
|
|
56
|
+
probe,
|
|
57
|
+
openclaw: openclawConfig,
|
|
58
|
+
openclawDir,
|
|
59
|
+
workspaceDir,
|
|
60
|
+
sessionsDir,
|
|
61
|
+
bootstrapMaxChars,
|
|
62
|
+
probeDir,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function assertOpenClawExists(cfg) {
|
|
66
|
+
if (!fs.existsSync(cfg.openclawDir)) {
|
|
67
|
+
console.error(`Error: OpenClaw directory not found at ${cfg.openclawDir}\n` +
|
|
68
|
+
`Set OPENCLAW_DIR environment variable or add "openclaw.dir" to ~/.clawprobe/config.json`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function deepMerge(...objects) {
|
|
73
|
+
const result = {};
|
|
74
|
+
for (const obj of objects) {
|
|
75
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
76
|
+
if (value !== undefined &&
|
|
77
|
+
value !== null &&
|
|
78
|
+
typeof value === "object" &&
|
|
79
|
+
!Array.isArray(value) &&
|
|
80
|
+
typeof result[key] === "object" &&
|
|
81
|
+
result[key] !== null &&
|
|
82
|
+
!Array.isArray(result[key])) {
|
|
83
|
+
result[key] = deepMerge(result[key], value);
|
|
84
|
+
}
|
|
85
|
+
else if (value !== undefined) {
|
|
86
|
+
result[key] = value;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { DatabaseSync } from "node:sqlite";
|
|
2
|
+
export interface SessionSnapshotRow {
|
|
3
|
+
id: number;
|
|
4
|
+
agent: string;
|
|
5
|
+
session_key: string;
|
|
6
|
+
session_id: string;
|
|
7
|
+
model: string | null;
|
|
8
|
+
provider: string | null;
|
|
9
|
+
input_tokens: number;
|
|
10
|
+
output_tokens: number;
|
|
11
|
+
total_tokens: number;
|
|
12
|
+
context_tokens: number;
|
|
13
|
+
compaction_count: number;
|
|
14
|
+
sampled_at: number;
|
|
15
|
+
}
|
|
16
|
+
export interface CostRecordRow {
|
|
17
|
+
id: number;
|
|
18
|
+
agent: string;
|
|
19
|
+
session_key: string;
|
|
20
|
+
date: string;
|
|
21
|
+
input_tokens: number;
|
|
22
|
+
output_tokens: number;
|
|
23
|
+
model: string | null;
|
|
24
|
+
estimated_usd: number;
|
|
25
|
+
recorded_at: number;
|
|
26
|
+
}
|
|
27
|
+
export interface CompactEventRow {
|
|
28
|
+
id: number;
|
|
29
|
+
agent: string;
|
|
30
|
+
session_key: string;
|
|
31
|
+
compaction_entry_id: string;
|
|
32
|
+
first_kept_entry_id: string;
|
|
33
|
+
tokens_before: number | null;
|
|
34
|
+
summary_text: string | null;
|
|
35
|
+
compacted_at: number | null;
|
|
36
|
+
compacted_message_count: number | null;
|
|
37
|
+
compacted_messages: string | null;
|
|
38
|
+
}
|
|
39
|
+
export interface FileSnapshotRow {
|
|
40
|
+
id: number;
|
|
41
|
+
agent: string;
|
|
42
|
+
file_path: string;
|
|
43
|
+
raw_chars: number;
|
|
44
|
+
injected_chars: number;
|
|
45
|
+
was_truncated: number;
|
|
46
|
+
sampled_at: number;
|
|
47
|
+
}
|
|
48
|
+
export interface SuggestionRow {
|
|
49
|
+
id: number;
|
|
50
|
+
agent: string;
|
|
51
|
+
rule_id: string;
|
|
52
|
+
severity: string;
|
|
53
|
+
title: string;
|
|
54
|
+
detail: string;
|
|
55
|
+
action: string | null;
|
|
56
|
+
created_at: number;
|
|
57
|
+
dismissed: number;
|
|
58
|
+
}
|
|
59
|
+
export declare function openDb(probeDir: string): DatabaseSync;
|
|
60
|
+
export declare function getDb(): DatabaseSync;
|
|
61
|
+
export declare function resetDb(): void;
|
|
62
|
+
export declare function insertSessionSnapshot(db: DatabaseSync, row: Omit<SessionSnapshotRow, "id">): void;
|
|
63
|
+
export declare function getFirstSnapshot(db: DatabaseSync, agent: string, sessionKey: string): SessionSnapshotRow | undefined;
|
|
64
|
+
export declare function getLatestSnapshot(db: DatabaseSync, agent: string, sessionKey: string): SessionSnapshotRow | undefined;
|
|
65
|
+
export declare function getAllSnapshots(db: DatabaseSync, agent: string, sessionKey: string): SessionSnapshotRow[];
|
|
66
|
+
export declare function getAllSessionKeys(db: DatabaseSync, agent: string): {
|
|
67
|
+
session_key: string;
|
|
68
|
+
last_sampled_at: number;
|
|
69
|
+
}[];
|
|
70
|
+
export declare function upsertCostRecord(db: DatabaseSync, row: Omit<CostRecordRow, "id">): void;
|
|
71
|
+
export declare function getDailyCostSummary(db: DatabaseSync, agent: string, days: number): {
|
|
72
|
+
date: string;
|
|
73
|
+
total_usd: number;
|
|
74
|
+
input_tokens: number;
|
|
75
|
+
output_tokens: number;
|
|
76
|
+
}[];
|
|
77
|
+
export declare function upsertCompactEvent(db: DatabaseSync, row: Omit<CompactEventRow, "id">): void;
|
|
78
|
+
export declare function getCompactEvents(db: DatabaseSync, agent: string, limit: number, sessionKey?: string): CompactEventRow[];
|
|
79
|
+
export declare function getCompactEventById(db: DatabaseSync, id: number): CompactEventRow | undefined;
|
|
80
|
+
export declare function insertFileSnapshot(db: DatabaseSync, row: Omit<FileSnapshotRow, "id">): void;
|
|
81
|
+
export declare function getLatestFileSnapshots(db: DatabaseSync, agent: string): FileSnapshotRow[];
|
|
82
|
+
export declare function upsertSuggestion(db: DatabaseSync, row: Omit<SuggestionRow, "id" | "dismissed">): void;
|
|
83
|
+
export declare function getSuggestions(db: DatabaseSync, agent: string, severity?: string): SuggestionRow[];
|
|
84
|
+
export declare function dismissSuggestion(db: DatabaseSync, agent: string, ruleId: string): void;
|
|
85
|
+
export declare function resetDismissed(db: DatabaseSync, agent: string): void;
|
|
86
|
+
export declare function removeSuggestion(db: DatabaseSync, agent: string, ruleId: string): void;
|
|
87
|
+
//# sourceMappingURL=db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/core/db.ts"],"names":[],"mappings":"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"}
|
package/dist/core/db.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { DatabaseSync } from "node:sqlite";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
const SCHEMA = `
|
|
5
|
+
PRAGMA journal_mode = WAL;
|
|
6
|
+
PRAGMA foreign_keys = ON;
|
|
7
|
+
|
|
8
|
+
CREATE TABLE IF NOT EXISTS session_snapshots (
|
|
9
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
10
|
+
agent TEXT NOT NULL,
|
|
11
|
+
session_key TEXT NOT NULL,
|
|
12
|
+
session_id TEXT NOT NULL,
|
|
13
|
+
model TEXT,
|
|
14
|
+
provider TEXT,
|
|
15
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
16
|
+
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
17
|
+
total_tokens INTEGER NOT NULL DEFAULT 0,
|
|
18
|
+
context_tokens INTEGER NOT NULL DEFAULT 0,
|
|
19
|
+
compaction_count INTEGER NOT NULL DEFAULT 0,
|
|
20
|
+
sampled_at INTEGER NOT NULL
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
CREATE INDEX IF NOT EXISTS idx_ss_agent_session ON session_snapshots(agent, session_key, sampled_at);
|
|
24
|
+
|
|
25
|
+
CREATE TABLE IF NOT EXISTS cost_records (
|
|
26
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
27
|
+
agent TEXT NOT NULL,
|
|
28
|
+
session_key TEXT NOT NULL,
|
|
29
|
+
date TEXT NOT NULL,
|
|
30
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
31
|
+
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
32
|
+
model TEXT,
|
|
33
|
+
estimated_usd REAL NOT NULL DEFAULT 0,
|
|
34
|
+
recorded_at INTEGER NOT NULL
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_cr_agent_date ON cost_records(agent, date);
|
|
38
|
+
|
|
39
|
+
CREATE TABLE IF NOT EXISTS compact_events (
|
|
40
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
41
|
+
agent TEXT NOT NULL,
|
|
42
|
+
session_key TEXT NOT NULL,
|
|
43
|
+
compaction_entry_id TEXT NOT NULL UNIQUE,
|
|
44
|
+
first_kept_entry_id TEXT NOT NULL,
|
|
45
|
+
tokens_before INTEGER,
|
|
46
|
+
summary_text TEXT,
|
|
47
|
+
compacted_at INTEGER,
|
|
48
|
+
compacted_message_count INTEGER,
|
|
49
|
+
compacted_messages TEXT
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
CREATE INDEX IF NOT EXISTS idx_ce_agent_session ON compact_events(agent, session_key);
|
|
53
|
+
|
|
54
|
+
CREATE TABLE IF NOT EXISTS file_snapshots (
|
|
55
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
56
|
+
agent TEXT NOT NULL,
|
|
57
|
+
file_path TEXT NOT NULL,
|
|
58
|
+
raw_chars INTEGER NOT NULL DEFAULT 0,
|
|
59
|
+
injected_chars INTEGER NOT NULL DEFAULT 0,
|
|
60
|
+
was_truncated INTEGER NOT NULL DEFAULT 0,
|
|
61
|
+
sampled_at INTEGER NOT NULL
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_fs_agent_path ON file_snapshots(agent, file_path, sampled_at);
|
|
65
|
+
|
|
66
|
+
CREATE TABLE IF NOT EXISTS suggestions (
|
|
67
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
68
|
+
agent TEXT NOT NULL,
|
|
69
|
+
rule_id TEXT NOT NULL,
|
|
70
|
+
severity TEXT NOT NULL,
|
|
71
|
+
title TEXT NOT NULL,
|
|
72
|
+
detail TEXT NOT NULL,
|
|
73
|
+
action TEXT,
|
|
74
|
+
created_at INTEGER NOT NULL,
|
|
75
|
+
dismissed INTEGER NOT NULL DEFAULT 0
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
CREATE INDEX IF NOT EXISTS idx_sg_agent_rule ON suggestions(agent, rule_id, dismissed);
|
|
79
|
+
`;
|
|
80
|
+
let _db = null;
|
|
81
|
+
export function openDb(probeDir) {
|
|
82
|
+
if (_db)
|
|
83
|
+
return _db;
|
|
84
|
+
fs.mkdirSync(probeDir, { recursive: true });
|
|
85
|
+
const dbPath = path.join(probeDir, "probe.db");
|
|
86
|
+
_db = new DatabaseSync(dbPath);
|
|
87
|
+
_db.exec(SCHEMA);
|
|
88
|
+
return _db;
|
|
89
|
+
}
|
|
90
|
+
export function getDb() {
|
|
91
|
+
if (!_db)
|
|
92
|
+
throw new Error("Database not initialized. Call openDb() first.");
|
|
93
|
+
return _db;
|
|
94
|
+
}
|
|
95
|
+
export function resetDb() {
|
|
96
|
+
if (_db) {
|
|
97
|
+
_db.close();
|
|
98
|
+
_db = null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// --- Session Snapshots ---
|
|
102
|
+
export function insertSessionSnapshot(db, row) {
|
|
103
|
+
db.prepare(`
|
|
104
|
+
INSERT INTO session_snapshots
|
|
105
|
+
(agent, session_key, session_id, model, provider,
|
|
106
|
+
input_tokens, output_tokens, total_tokens, context_tokens,
|
|
107
|
+
compaction_count, sampled_at)
|
|
108
|
+
VALUES
|
|
109
|
+
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
110
|
+
`).run(row.agent, row.session_key, row.session_id, row.model, row.provider, row.input_tokens, row.output_tokens, row.total_tokens, row.context_tokens, row.compaction_count, row.sampled_at);
|
|
111
|
+
}
|
|
112
|
+
export function getFirstSnapshot(db, agent, sessionKey) {
|
|
113
|
+
return db.prepare(`
|
|
114
|
+
SELECT * FROM session_snapshots
|
|
115
|
+
WHERE agent = ? AND session_key = ?
|
|
116
|
+
ORDER BY sampled_at ASC
|
|
117
|
+
LIMIT 1
|
|
118
|
+
`).get(agent, sessionKey);
|
|
119
|
+
}
|
|
120
|
+
export function getLatestSnapshot(db, agent, sessionKey) {
|
|
121
|
+
return db.prepare(`
|
|
122
|
+
SELECT * FROM session_snapshots
|
|
123
|
+
WHERE agent = ? AND session_key = ?
|
|
124
|
+
ORDER BY sampled_at DESC
|
|
125
|
+
LIMIT 1
|
|
126
|
+
`).get(agent, sessionKey);
|
|
127
|
+
}
|
|
128
|
+
export function getAllSnapshots(db, agent, sessionKey) {
|
|
129
|
+
return db.prepare(`
|
|
130
|
+
SELECT * FROM session_snapshots
|
|
131
|
+
WHERE agent = ? AND session_key = ?
|
|
132
|
+
ORDER BY sampled_at ASC
|
|
133
|
+
`).all(agent, sessionKey);
|
|
134
|
+
}
|
|
135
|
+
export function getAllSessionKeys(db, agent) {
|
|
136
|
+
return db.prepare(`
|
|
137
|
+
SELECT session_key, MAX(sampled_at) as last_sampled_at
|
|
138
|
+
FROM session_snapshots
|
|
139
|
+
WHERE agent = ?
|
|
140
|
+
GROUP BY session_key
|
|
141
|
+
ORDER BY last_sampled_at DESC
|
|
142
|
+
`).all(agent);
|
|
143
|
+
}
|
|
144
|
+
// --- Cost Records ---
|
|
145
|
+
export function upsertCostRecord(db, row) {
|
|
146
|
+
db.prepare(`
|
|
147
|
+
INSERT INTO cost_records
|
|
148
|
+
(agent, session_key, date, input_tokens, output_tokens, model, estimated_usd, recorded_at)
|
|
149
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
150
|
+
`).run(row.agent, row.session_key, row.date, row.input_tokens, row.output_tokens, row.model, row.estimated_usd, row.recorded_at);
|
|
151
|
+
}
|
|
152
|
+
export function getDailyCostSummary(db, agent, days) {
|
|
153
|
+
const cutoff = new Date(Date.now() - days * 86400_000).toISOString().slice(0, 10);
|
|
154
|
+
return db.prepare(`
|
|
155
|
+
SELECT
|
|
156
|
+
date,
|
|
157
|
+
SUM(estimated_usd) AS total_usd,
|
|
158
|
+
SUM(input_tokens) AS input_tokens,
|
|
159
|
+
SUM(output_tokens) AS output_tokens
|
|
160
|
+
FROM cost_records
|
|
161
|
+
WHERE agent = ? AND date >= ?
|
|
162
|
+
GROUP BY date
|
|
163
|
+
ORDER BY date ASC
|
|
164
|
+
`).all(agent, cutoff);
|
|
165
|
+
}
|
|
166
|
+
// --- Compact Events ---
|
|
167
|
+
export function upsertCompactEvent(db, row) {
|
|
168
|
+
db.prepare(`
|
|
169
|
+
INSERT OR REPLACE INTO compact_events
|
|
170
|
+
(agent, session_key, compaction_entry_id, first_kept_entry_id,
|
|
171
|
+
tokens_before, summary_text, compacted_at,
|
|
172
|
+
compacted_message_count, compacted_messages)
|
|
173
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
174
|
+
`).run(row.agent, row.session_key, row.compaction_entry_id, row.first_kept_entry_id, row.tokens_before, row.summary_text, row.compacted_at, row.compacted_message_count, row.compacted_messages);
|
|
175
|
+
}
|
|
176
|
+
export function getCompactEvents(db, agent, limit, sessionKey) {
|
|
177
|
+
if (sessionKey) {
|
|
178
|
+
return db.prepare(`
|
|
179
|
+
SELECT * FROM compact_events
|
|
180
|
+
WHERE agent = ? AND session_key = ?
|
|
181
|
+
ORDER BY compacted_at DESC
|
|
182
|
+
LIMIT ?
|
|
183
|
+
`).all(agent, sessionKey, limit);
|
|
184
|
+
}
|
|
185
|
+
return db.prepare(`
|
|
186
|
+
SELECT * FROM compact_events
|
|
187
|
+
WHERE agent = ?
|
|
188
|
+
ORDER BY compacted_at DESC
|
|
189
|
+
LIMIT ?
|
|
190
|
+
`).all(agent, limit);
|
|
191
|
+
}
|
|
192
|
+
export function getCompactEventById(db, id) {
|
|
193
|
+
return db.prepare(`SELECT * FROM compact_events WHERE id = ?`).get(id);
|
|
194
|
+
}
|
|
195
|
+
// --- File Snapshots ---
|
|
196
|
+
export function insertFileSnapshot(db, row) {
|
|
197
|
+
db.prepare(`
|
|
198
|
+
INSERT INTO file_snapshots
|
|
199
|
+
(agent, file_path, raw_chars, injected_chars, was_truncated, sampled_at)
|
|
200
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
201
|
+
`).run(row.agent, row.file_path, row.raw_chars, row.injected_chars, row.was_truncated, row.sampled_at);
|
|
202
|
+
}
|
|
203
|
+
export function getLatestFileSnapshots(db, agent) {
|
|
204
|
+
return db.prepare(`
|
|
205
|
+
SELECT fs.*
|
|
206
|
+
FROM file_snapshots fs
|
|
207
|
+
INNER JOIN (
|
|
208
|
+
SELECT file_path, MAX(sampled_at) AS max_at
|
|
209
|
+
FROM file_snapshots
|
|
210
|
+
WHERE agent = ?
|
|
211
|
+
GROUP BY file_path
|
|
212
|
+
) latest ON fs.file_path = latest.file_path AND fs.sampled_at = latest.max_at
|
|
213
|
+
WHERE fs.agent = ?
|
|
214
|
+
ORDER BY fs.raw_chars DESC
|
|
215
|
+
`).all(agent, agent);
|
|
216
|
+
}
|
|
217
|
+
// --- Suggestions ---
|
|
218
|
+
export function upsertSuggestion(db, row) {
|
|
219
|
+
const existing = db.prepare(`
|
|
220
|
+
SELECT id, dismissed FROM suggestions
|
|
221
|
+
WHERE agent = ? AND rule_id = ?
|
|
222
|
+
`).get(row.agent, row.rule_id);
|
|
223
|
+
if (existing) {
|
|
224
|
+
if (existing.dismissed)
|
|
225
|
+
return;
|
|
226
|
+
db.prepare(`
|
|
227
|
+
UPDATE suggestions
|
|
228
|
+
SET severity = ?, title = ?, detail = ?, action = ?, created_at = ?
|
|
229
|
+
WHERE id = ?
|
|
230
|
+
`).run(row.severity, row.title, row.detail, row.action, row.created_at, existing.id);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
db.prepare(`
|
|
234
|
+
INSERT INTO suggestions
|
|
235
|
+
(agent, rule_id, severity, title, detail, action, created_at, dismissed)
|
|
236
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, 0)
|
|
237
|
+
`).run(row.agent, row.rule_id, row.severity, row.title, row.detail, row.action, row.created_at);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
export function getSuggestions(db, agent, severity) {
|
|
241
|
+
if (severity) {
|
|
242
|
+
return db.prepare(`
|
|
243
|
+
SELECT * FROM suggestions
|
|
244
|
+
WHERE agent = ? AND dismissed = 0 AND severity = ?
|
|
245
|
+
ORDER BY CASE severity WHEN 'critical' THEN 0 WHEN 'warning' THEN 1 ELSE 2 END, created_at DESC
|
|
246
|
+
`).all(agent, severity);
|
|
247
|
+
}
|
|
248
|
+
return db.prepare(`
|
|
249
|
+
SELECT * FROM suggestions
|
|
250
|
+
WHERE agent = ? AND dismissed = 0
|
|
251
|
+
ORDER BY CASE severity WHEN 'critical' THEN 0 WHEN 'warning' THEN 1 ELSE 2 END, created_at DESC
|
|
252
|
+
`).all(agent);
|
|
253
|
+
}
|
|
254
|
+
export function dismissSuggestion(db, agent, ruleId) {
|
|
255
|
+
db.prepare(`UPDATE suggestions SET dismissed = 1 WHERE agent = ? AND rule_id = ?`).run(agent, ruleId);
|
|
256
|
+
}
|
|
257
|
+
export function resetDismissed(db, agent) {
|
|
258
|
+
db.prepare(`UPDATE suggestions SET dismissed = 0 WHERE agent = ?`).run(agent);
|
|
259
|
+
}
|
|
260
|
+
export function removeSuggestion(db, agent, ruleId) {
|
|
261
|
+
db.prepare(`DELETE FROM suggestions WHERE agent = ? AND rule_id = ?`).run(agent, ruleId);
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/core/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface SessionHeader {
|
|
2
|
+
type: "session";
|
|
3
|
+
id: string;
|
|
4
|
+
cwd: string;
|
|
5
|
+
timestamp: number;
|
|
6
|
+
parentSession?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface MessageEntry {
|
|
9
|
+
type: "message";
|
|
10
|
+
id: string;
|
|
11
|
+
parentId: string;
|
|
12
|
+
role: "user" | "assistant" | "tool";
|
|
13
|
+
content: string;
|
|
14
|
+
timestamp?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface CompactionEntry {
|
|
17
|
+
type: "compaction";
|
|
18
|
+
id: string;
|
|
19
|
+
parentId: string;
|
|
20
|
+
firstKeptEntryId: string;
|
|
21
|
+
tokensBefore: number;
|
|
22
|
+
content: string;
|
|
23
|
+
timestamp?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface CustomMessageEntry {
|
|
26
|
+
type: "custom_message";
|
|
27
|
+
id: string;
|
|
28
|
+
parentId: string;
|
|
29
|
+
role: string;
|
|
30
|
+
content: string;
|
|
31
|
+
hidden?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export type JournalEntry = SessionHeader | MessageEntry | CompactionEntry | CustomMessageEntry | {
|
|
34
|
+
type: string;
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
};
|
|
37
|
+
export interface CompactEvent {
|
|
38
|
+
entryId: string;
|
|
39
|
+
parentId: string;
|
|
40
|
+
firstKeptEntryId: string;
|
|
41
|
+
tokensBefore: number;
|
|
42
|
+
summaryText: string;
|
|
43
|
+
timestamp?: number;
|
|
44
|
+
lineIndex: number;
|
|
45
|
+
}
|
|
46
|
+
export interface ParseResult {
|
|
47
|
+
entries: JournalEntry[];
|
|
48
|
+
compactEvents: CompactEvent[];
|
|
49
|
+
}
|
|
50
|
+
export declare function parseAll(filePath: string): ParseResult;
|
|
51
|
+
export declare function parseIncremental(filePath: string): ParseResult;
|
|
52
|
+
export declare function resetCursor(filePath: string): void;
|
|
53
|
+
export declare function getCompactedMessages(allEntries: JournalEntry[], compactEvent: CompactEvent, previousFirstKeptId?: string): MessageEntry[];
|
|
54
|
+
export declare function buildConversationTree(entries: JournalEntry[]): MessageEntry[];
|
|
55
|
+
//# sourceMappingURL=jsonl-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl-parser.d.ts","sourceRoot":"","sources":["../../src/core/jsonl-parser.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,gBAAgB,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,YAAY,GACpB,aAAa,GACb,YAAY,GACZ,eAAe,GACf,kBAAkB,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAI7C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B;AAMD,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAGtD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAqD9D;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAElD;AAID,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,YAAY,EAAE,EAC1B,YAAY,EAAE,YAAY,EAC1B,mBAAmB,CAAC,EAAE,MAAM,GAC3B,YAAY,EAAE,CAmBhB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAG7E"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
// --- Incremental cursor state ---
|
|
3
|
+
const fileCursors = new Map();
|
|
4
|
+
export function parseAll(filePath) {
|
|
5
|
+
fileCursors.delete(filePath);
|
|
6
|
+
return parseIncremental(filePath);
|
|
7
|
+
}
|
|
8
|
+
export function parseIncremental(filePath) {
|
|
9
|
+
if (!fs.existsSync(filePath)) {
|
|
10
|
+
return { entries: [], compactEvents: [] };
|
|
11
|
+
}
|
|
12
|
+
const fd = fs.openSync(filePath, "r");
|
|
13
|
+
const stat = fs.fstatSync(fd);
|
|
14
|
+
const fileSize = stat.size;
|
|
15
|
+
const cursor = fileCursors.get(filePath) ?? 0;
|
|
16
|
+
if (cursor >= fileSize) {
|
|
17
|
+
fs.closeSync(fd);
|
|
18
|
+
return { entries: [], compactEvents: [] };
|
|
19
|
+
}
|
|
20
|
+
const chunkSize = fileSize - cursor;
|
|
21
|
+
const buf = Buffer.allocUnsafe(chunkSize);
|
|
22
|
+
fs.readSync(fd, buf, 0, chunkSize, cursor);
|
|
23
|
+
fs.closeSync(fd);
|
|
24
|
+
fileCursors.set(filePath, fileSize);
|
|
25
|
+
const newText = buf.toString("utf-8");
|
|
26
|
+
const lines = newText.split("\n").filter((l) => l.trim().length > 0);
|
|
27
|
+
const entries = [];
|
|
28
|
+
const compactEvents = [];
|
|
29
|
+
let lineIndex = 0;
|
|
30
|
+
for (const line of lines) {
|
|
31
|
+
try {
|
|
32
|
+
const entry = JSON.parse(line);
|
|
33
|
+
entries.push(entry);
|
|
34
|
+
if (entry.type === "compaction") {
|
|
35
|
+
const ce = entry;
|
|
36
|
+
compactEvents.push({
|
|
37
|
+
entryId: ce.id,
|
|
38
|
+
parentId: ce.parentId,
|
|
39
|
+
firstKeptEntryId: ce.firstKeptEntryId,
|
|
40
|
+
tokensBefore: ce.tokensBefore,
|
|
41
|
+
summaryText: ce.content,
|
|
42
|
+
timestamp: ce.timestamp,
|
|
43
|
+
lineIndex,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
lineIndex++;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// skip malformed lines
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { entries, compactEvents };
|
|
53
|
+
}
|
|
54
|
+
export function resetCursor(filePath) {
|
|
55
|
+
fileCursors.delete(filePath);
|
|
56
|
+
}
|
|
57
|
+
// --- Full analysis helpers ---
|
|
58
|
+
export function getCompactedMessages(allEntries, compactEvent, previousFirstKeptId) {
|
|
59
|
+
const messages = allEntries.filter((e) => e.type === "message");
|
|
60
|
+
// Entries after the previous compact boundary, before this compact's firstKeptEntryId
|
|
61
|
+
let started = previousFirstKeptId === undefined;
|
|
62
|
+
const result = [];
|
|
63
|
+
for (const msg of messages) {
|
|
64
|
+
if (!started) {
|
|
65
|
+
if (msg.id === previousFirstKeptId)
|
|
66
|
+
started = true;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (msg.id === compactEvent.firstKeptEntryId)
|
|
70
|
+
break;
|
|
71
|
+
result.push(msg);
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
export function buildConversationTree(entries) {
|
|
76
|
+
// Return messages in insertion order (they form a linear chain via parentId)
|
|
77
|
+
return entries.filter((e) => e.type === "message");
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=jsonl-parser.js.map
|