@evomap/evolver-runtime-adapters 2.0.0-beta.0 → 2.0.0-beta.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/dist/adapters.d.ts +1 -0
- package/dist/adapters.js +196 -10
- package/dist/cursorState.js +14 -5
- package/dist/types.d.ts +3 -0
- package/dist/types.js +6 -2
- package/package.json +2 -1
package/dist/adapters.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare const claudeCodeAdapter: SessionLogAdapter;
|
|
|
3
3
|
export declare const cursorAdapter: SessionLogAdapter;
|
|
4
4
|
export declare const codexAdapter: SessionLogAdapter;
|
|
5
5
|
export declare const geminiAdapter: SessionLogAdapter;
|
|
6
|
+
export declare const antigravityAdapter: SessionLogAdapter;
|
|
6
7
|
export declare const genericChatAdapter: SessionLogAdapter;
|
|
7
8
|
export declare const kimiAdapter: SessionLogAdapter;
|
|
8
9
|
export declare const ADAPTERS: readonly SessionLogAdapter[];
|
package/dist/adapters.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseJsonlLines, extractContent, isMetaText, correlateToolNames } from './types.js';
|
|
1
|
+
import { parseJsonlLines, extractContent, isMetaText, correlateToolNames, stripUtf8Bom } from './types.js';
|
|
2
2
|
function isRecord(value) {
|
|
3
3
|
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
4
4
|
}
|
|
@@ -24,7 +24,7 @@ function firstString(record, keys) {
|
|
|
24
24
|
function parseJsonish(value) {
|
|
25
25
|
if (typeof value !== 'string')
|
|
26
26
|
return value;
|
|
27
|
-
const trimmed = value.trim();
|
|
27
|
+
const trimmed = stripUtf8Bom(value).trim();
|
|
28
28
|
if (!trimmed || (!trimmed.startsWith('{') && !trimmed.startsWith('[')))
|
|
29
29
|
return value;
|
|
30
30
|
try {
|
|
@@ -142,9 +142,9 @@ function withSourceMetadata(turns, source) {
|
|
|
142
142
|
}
|
|
143
143
|
// VERIFICATION BAR: an adapter only ships once its parse() is checked against a REAL session log from that tool
|
|
144
144
|
// — a trimmed, sanitized sample + a golden test (see the golden tests in adapters.test.ts). A guessed schema is
|
|
145
|
-
// worse than no adapter: it silently yields 0 turns on real logs while looking supported. Today: claude-code
|
|
146
|
-
// codex
|
|
147
|
-
//
|
|
145
|
+
// worse than no adapter: it silently yields 0 turns on real logs while looking supported. Today: claude-code,
|
|
146
|
+
// codex, cursor, Gemini, and Antigravity are verified against trimmed sanitized real-log samples. opencode/kiro
|
|
147
|
+
// stay removed until each has a real-log golden test.
|
|
148
148
|
// claude-code AND cursor share the Anthropic content-block transcript shape: one JSONL record per turn,
|
|
149
149
|
// { role|type: 'user'|'assistant', message: { content: [ {type:'text',text} | {type:'tool_use',name,id?} |
|
|
150
150
|
// {type:'tool_result',...} ] } }. correlateToolNames backfills a tool_result's tool name from its tool_use id.
|
|
@@ -559,7 +559,7 @@ function geminiSessionFromValue(value) {
|
|
|
559
559
|
};
|
|
560
560
|
}
|
|
561
561
|
function geminiSessions(chunk) {
|
|
562
|
-
const trimmed = chunk.trim();
|
|
562
|
+
const trimmed = stripUtf8Bom(chunk).trim();
|
|
563
563
|
if (!trimmed)
|
|
564
564
|
return [];
|
|
565
565
|
// Gemini session files are a single JSON document. Tolerate JSONL-of-sessions too.
|
|
@@ -591,6 +591,192 @@ export const geminiAdapter = {
|
|
|
591
591
|
parseSession: (chunk) => geminiSessions(chunk)[0] ?? { turns: [] },
|
|
592
592
|
parseSessions: geminiSessions,
|
|
593
593
|
};
|
|
594
|
+
// Antigravity persists one JSON record per event at
|
|
595
|
+
// ~/.gemini/{antigravity,antigravity-ide}/brain/<uuid>/.system_generated/logs/transcript.jsonl.
|
|
596
|
+
// Verified real records carry {type,status,source,step_index,created_at,content}; PLANNER_RESPONSE additionally
|
|
597
|
+
// carries plaintext `thinking` and tool_calls: [{name,args}]. The file can append a newer snapshot of an earlier
|
|
598
|
+
// step, so the last terminal record for each type + step_index is authoritative.
|
|
599
|
+
const ANTIGRAVITY_TRANSCRIPT_PATH = /(?:^|[/\\])\.gemini[/\\](?:antigravity|antigravity-ide)[/\\]brain[/\\]([0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12})[/\\]\.system_generated[/\\]logs[/\\]transcript\.jsonl$/i;
|
|
600
|
+
const ANTIGRAVITY_TERMINAL_STATUSES = new Set(['DONE', 'ERROR', 'CANCELED']);
|
|
601
|
+
const ANTIGRAVITY_TOOL_RESULT_TYPES = new Set([
|
|
602
|
+
'ASK_QUESTION',
|
|
603
|
+
'CODE_ACTION',
|
|
604
|
+
'GENERIC',
|
|
605
|
+
'GREP_SEARCH',
|
|
606
|
+
'LIST_DIRECTORY',
|
|
607
|
+
'RUN_COMMAND',
|
|
608
|
+
'SEARCH_WEB',
|
|
609
|
+
'VIEW_FILE',
|
|
610
|
+
]);
|
|
611
|
+
function antigravityStatus(record) {
|
|
612
|
+
return typeof record['status'] === 'string' ? record['status'].toUpperCase() : '';
|
|
613
|
+
}
|
|
614
|
+
function antigravityRecords(chunk) {
|
|
615
|
+
const selected = new Map();
|
|
616
|
+
parseJsonlLines(chunk).forEach((record, rowIndex) => {
|
|
617
|
+
const type = typeof record['type'] === 'string' ? record['type'] : '';
|
|
618
|
+
const stepIndex = finiteNumber(record['step_index']);
|
|
619
|
+
const key = type && stepIndex !== undefined ? `${type}\u0000${stepIndex}` : `row\u0000${rowIndex}`;
|
|
620
|
+
const current = selected.get(key);
|
|
621
|
+
if (!current) {
|
|
622
|
+
selected.set(key, { record, rowIndex });
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
const currentTerminal = ANTIGRAVITY_TERMINAL_STATUSES.has(antigravityStatus(current.record));
|
|
626
|
+
const nextTerminal = ANTIGRAVITY_TERMINAL_STATUSES.has(antigravityStatus(record));
|
|
627
|
+
if (!currentTerminal || nextTerminal) {
|
|
628
|
+
// Snapshot rows are partial: omitted tool_calls carry forward, while an explicit value (including []) wins.
|
|
629
|
+
// Keep the first logical position so a late terminal snapshot cannot move a tool call after its result.
|
|
630
|
+
const selectedRecord = type === 'PLANNER_RESPONSE'
|
|
631
|
+
&& !hasOwn(record, 'tool_calls')
|
|
632
|
+
&& hasOwn(current.record, 'tool_calls')
|
|
633
|
+
? { ...record, tool_calls: current.record['tool_calls'] }
|
|
634
|
+
: record;
|
|
635
|
+
selected.set(key, { record: selectedRecord, rowIndex: current.rowIndex });
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
return [...selected.values()]
|
|
639
|
+
.sort((a, b) => a.rowIndex - b.rowIndex)
|
|
640
|
+
.map(({ record }) => record);
|
|
641
|
+
}
|
|
642
|
+
function antigravityRecordMetadata(record) {
|
|
643
|
+
const metadata = {};
|
|
644
|
+
for (const key of ['type', 'status', 'source', 'step_index', 'created_at']) {
|
|
645
|
+
if (record[key] !== undefined)
|
|
646
|
+
metadata[key] = record[key];
|
|
647
|
+
}
|
|
648
|
+
return metadata;
|
|
649
|
+
}
|
|
650
|
+
function antigravityRecordText(record, key = 'content') {
|
|
651
|
+
return typeof record[key] === 'string' ? record[key] : '';
|
|
652
|
+
}
|
|
653
|
+
function antigravityFailure(record) {
|
|
654
|
+
const type = typeof record['type'] === 'string' ? record['type'] : '';
|
|
655
|
+
const status = antigravityStatus(record);
|
|
656
|
+
if (type !== 'ERROR_MESSAGE' && status !== 'ERROR' && status !== 'CANCELED')
|
|
657
|
+
return undefined;
|
|
658
|
+
return antigravityRecordText(record, 'error')
|
|
659
|
+
|| antigravityRecordText(record)
|
|
660
|
+
|| `Antigravity ${type || 'record'} ${status || 'ERROR'}`;
|
|
661
|
+
}
|
|
662
|
+
function annotateAntigravityTurns(record, turns) {
|
|
663
|
+
const timestamp = typeof record['created_at'] === 'string' ? record['created_at'] : undefined;
|
|
664
|
+
const metadata = antigravityRecordMetadata(record);
|
|
665
|
+
const errorMessage = antigravityFailure(record);
|
|
666
|
+
return turns.map((turn) => ({
|
|
667
|
+
...turn,
|
|
668
|
+
...(timestamp ? { timestamp } : {}),
|
|
669
|
+
...(errorMessage && !turn.errorMessage ? { errorMessage } : {}),
|
|
670
|
+
metadata,
|
|
671
|
+
sourceRecord: record,
|
|
672
|
+
rawRow: record,
|
|
673
|
+
}));
|
|
674
|
+
}
|
|
675
|
+
function antigravityResultTypeForTool(toolName) {
|
|
676
|
+
switch (toolName.toLowerCase()) {
|
|
677
|
+
case 'ask_question': return 'ASK_QUESTION';
|
|
678
|
+
case 'grep_search': return 'GREP_SEARCH';
|
|
679
|
+
case 'list_dir': return 'LIST_DIRECTORY';
|
|
680
|
+
case 'run_command': return 'RUN_COMMAND';
|
|
681
|
+
case 'search_web': return 'SEARCH_WEB';
|
|
682
|
+
case 'view_file': return 'VIEW_FILE';
|
|
683
|
+
case 'multi_replace_file_content':
|
|
684
|
+
case 'replace_file_content':
|
|
685
|
+
case 'write_to_file': return 'CODE_ACTION';
|
|
686
|
+
default: return 'GENERIC';
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
function antigravityFallbackToolName(resultType) {
|
|
690
|
+
switch (resultType) {
|
|
691
|
+
case 'ASK_QUESTION': return 'ask_question';
|
|
692
|
+
case 'CODE_ACTION': return 'code_action';
|
|
693
|
+
case 'GREP_SEARCH': return 'grep_search';
|
|
694
|
+
case 'LIST_DIRECTORY': return 'list_dir';
|
|
695
|
+
case 'RUN_COMMAND': return 'run_command';
|
|
696
|
+
case 'SEARCH_WEB': return 'search_web';
|
|
697
|
+
case 'VIEW_FILE': return 'view_file';
|
|
698
|
+
default: return 'generic';
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
function antigravityTranscriptFromRecords(records) {
|
|
702
|
+
const turns = [];
|
|
703
|
+
const pendingTools = [];
|
|
704
|
+
records.forEach((record, rowIndex) => {
|
|
705
|
+
const type = typeof record['type'] === 'string' ? record['type'] : '';
|
|
706
|
+
const content = antigravityRecordText(record);
|
|
707
|
+
const recordTurns = [];
|
|
708
|
+
if (type === 'USER_INPUT') {
|
|
709
|
+
recordTurns.push({ role: 'user', text: content, isMeta: isMetaText(content) });
|
|
710
|
+
}
|
|
711
|
+
else if (type === 'PLANNER_RESPONSE') {
|
|
712
|
+
const thinking = antigravityRecordText(record, 'thinking');
|
|
713
|
+
if (thinking)
|
|
714
|
+
recordTurns.push({ role: 'assistant', text: thinking, reasoning: true, isMeta: false });
|
|
715
|
+
if (content)
|
|
716
|
+
recordTurns.push({ role: 'assistant', text: content, isMeta: isMetaText(content) });
|
|
717
|
+
const toolCalls = Array.isArray(record['tool_calls']) ? record['tool_calls'] : [];
|
|
718
|
+
toolCalls.forEach((value, ordinal) => {
|
|
719
|
+
if (!isRecord(value))
|
|
720
|
+
return;
|
|
721
|
+
const toolName = typeof value['name'] === 'string' && value['name'] ? value['name'] : 'antigravity_tool';
|
|
722
|
+
const stepIndex = finiteNumber(record['step_index']);
|
|
723
|
+
const toolUseId = `antigravity:${stepIndex ?? `row-${rowIndex}`}:${ordinal}`;
|
|
724
|
+
pendingTools.push({ toolName, toolUseId, resultType: antigravityResultTypeForTool(toolName) });
|
|
725
|
+
recordTurns.push({
|
|
726
|
+
role: 'assistant',
|
|
727
|
+
text: '',
|
|
728
|
+
toolName,
|
|
729
|
+
toolUseId,
|
|
730
|
+
...(hasOwn(value, 'args') ? { toolInput: value['args'] } : {}),
|
|
731
|
+
isMeta: false,
|
|
732
|
+
});
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
else if (ANTIGRAVITY_TOOL_RESULT_TYPES.has(type)) {
|
|
736
|
+
const pendingIndex = pendingTools.findIndex((pending) => pending.resultType === type);
|
|
737
|
+
const pending = pendingIndex >= 0 ? pendingTools.splice(pendingIndex, 1)[0] : undefined;
|
|
738
|
+
recordTurns.push({
|
|
739
|
+
role: 'tool',
|
|
740
|
+
text: '',
|
|
741
|
+
toolName: pending?.toolName ?? antigravityFallbackToolName(type),
|
|
742
|
+
...(pending ? { toolUseId: pending.toolUseId } : {}),
|
|
743
|
+
toolResult: content,
|
|
744
|
+
isMeta: false,
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
else if (type === 'ERROR_MESSAGE') {
|
|
748
|
+
const errorMessage = antigravityFailure(record);
|
|
749
|
+
recordTurns.push({ role: 'system', text: content || errorMessage, errorMessage, isMeta: true });
|
|
750
|
+
}
|
|
751
|
+
else if (type === 'SYSTEM_MESSAGE' || type === 'CONVERSATION_HISTORY' || type === 'CHECKPOINT') {
|
|
752
|
+
recordTurns.push({ role: 'system', text: content, isMeta: true });
|
|
753
|
+
}
|
|
754
|
+
turns.push(...annotateAntigravityTurns(record, recordTurns));
|
|
755
|
+
});
|
|
756
|
+
return turns;
|
|
757
|
+
}
|
|
758
|
+
function antigravitySession(chunk) {
|
|
759
|
+
const records = antigravityRecords(chunk);
|
|
760
|
+
const startedAt = records.find((record) => typeof record['created_at'] === 'string')?.['created_at'];
|
|
761
|
+
return {
|
|
762
|
+
turns: antigravityTranscriptFromRecords(records),
|
|
763
|
+
provider: 'antigravity',
|
|
764
|
+
clientSource: 'antigravity',
|
|
765
|
+
...(typeof startedAt === 'string' ? { startedAt } : {}),
|
|
766
|
+
rawRows: records,
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
export const antigravityAdapter = {
|
|
770
|
+
agent: 'antigravity',
|
|
771
|
+
detect: (path) => ANTIGRAVITY_TRANSCRIPT_PATH.test(path),
|
|
772
|
+
sessionIdFromPath: (path) => ANTIGRAVITY_TRANSCRIPT_PATH.exec(path)?.[1],
|
|
773
|
+
parse: (chunk) => antigravitySession(chunk).turns,
|
|
774
|
+
parseSession: antigravitySession,
|
|
775
|
+
parseSessions: (chunk) => {
|
|
776
|
+
const session = antigravitySession(chunk);
|
|
777
|
+
return session.turns.length > 0 ? [session] : [];
|
|
778
|
+
},
|
|
779
|
+
};
|
|
594
780
|
// ── generic chat-transcript adapter ──────────────────────────────────────────
|
|
595
781
|
// The per-tool adapters above are gated on a REAL private-log golden (a guessed private schema silently yields 0
|
|
596
782
|
// turns). This one is different ON PURPOSE: it targets the DOCUMENTED, stable interchange format — OpenAI
|
|
@@ -935,7 +1121,7 @@ function applyGenericSessionMetadata(turns, metadata) {
|
|
|
935
1121
|
* chat-completions request-body shape), or a SINGLE message object (incl. pretty-printed multi-line — which is
|
|
936
1122
|
* not valid JSONL, so it must be handled here, not fall through). */
|
|
937
1123
|
function genericChatRecords(chunk) {
|
|
938
|
-
const trimmed = chunk.trim();
|
|
1124
|
+
const trimmed = stripUtf8Bom(chunk).trim();
|
|
939
1125
|
if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
|
|
940
1126
|
try {
|
|
941
1127
|
const parsed = JSON.parse(trimmed);
|
|
@@ -970,7 +1156,7 @@ function genericChatSessionsFromValue(value) {
|
|
|
970
1156
|
return session.turns.length > 0 ? [session] : [];
|
|
971
1157
|
}
|
|
972
1158
|
function genericChatSessions(chunk) {
|
|
973
|
-
const trimmed = chunk.trim();
|
|
1159
|
+
const trimmed = stripUtf8Bom(chunk).trim();
|
|
974
1160
|
if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
|
|
975
1161
|
try {
|
|
976
1162
|
const parsed = JSON.parse(trimmed);
|
|
@@ -1032,6 +1218,6 @@ export const kimiAdapter = {
|
|
|
1032
1218
|
parseSessions: kimiSessions,
|
|
1033
1219
|
};
|
|
1034
1220
|
// Only verified adapters are registered. opencode/kiro live in git history — re-add with a real-log fixture.
|
|
1035
|
-
// genericChatAdapter is LAST so any tool-specific path (claude/cursor/codex/gemini/kimi) resolves first.
|
|
1036
|
-
export const ADAPTERS = [claudeCodeAdapter, codexAdapter, cursorAdapter, geminiAdapter, kimiAdapter, genericChatAdapter];
|
|
1221
|
+
// genericChatAdapter is LAST so any tool-specific path (claude/cursor/codex/gemini/antigravity/kimi) resolves first.
|
|
1222
|
+
export const ADAPTERS = [claudeCodeAdapter, codexAdapter, cursorAdapter, geminiAdapter, antigravityAdapter, kimiAdapter, genericChatAdapter];
|
|
1037
1223
|
export function adapterForPath(path) { return ADAPTERS.find((a) => a.detect(path)); }
|
package/dist/cursorState.js
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { correlateToolNames, isMetaText } from './types.js';
|
|
3
|
-
// node:sqlite is a recent Node built-in exposed only as `node:sqlite` (no bare `sqlite` alias). Load it through
|
|
4
|
-
// createRequire so bundlers (vitest/vite) don't statically strip the prefix and fail resolution — mirrors the
|
|
5
|
-
// pattern already used by evolver-core/src/mailbox/store.ts.
|
|
6
3
|
const nodeRequire = createRequire(import.meta.url);
|
|
4
|
+
function isBunRuntime() {
|
|
5
|
+
return typeof process.versions === 'object' && typeof process.versions.bun === 'string';
|
|
6
|
+
}
|
|
7
|
+
function openReadOnlySqliteDatabase(path) {
|
|
8
|
+
if (isBunRuntime()) {
|
|
9
|
+
const { Database } = nodeRequire('bun:sqlite');
|
|
10
|
+
return new Database(path, { readonly: true });
|
|
11
|
+
}
|
|
12
|
+
// node:sqlite is exposed only as `node:sqlite` (no bare `sqlite` alias). Load it through createRequire so
|
|
13
|
+
// bundlers do not statically strip the prefix and break Vitest/Vite or Bun standalone builds.
|
|
14
|
+
const { DatabaseSync } = nodeRequire('node:sqlite');
|
|
15
|
+
return new DatabaseSync(path, { readOnly: true });
|
|
16
|
+
}
|
|
7
17
|
// ── Cursor state.vscdb conversation extraction ───────────────────────────────
|
|
8
18
|
//
|
|
9
19
|
// VERIFICATION STATUS / COVERAGE (honest scope — read before extending):
|
|
@@ -151,8 +161,7 @@ function composerToSession(composer, composerId, readBubble) {
|
|
|
151
161
|
export function parseCursorStateVscdb(dbPath) {
|
|
152
162
|
let db;
|
|
153
163
|
try {
|
|
154
|
-
|
|
155
|
-
db = new DatabaseSync(dbPath, { readOnly: true });
|
|
164
|
+
db = openReadOnlySqliteDatabase(dbPath);
|
|
156
165
|
const composerRows = db
|
|
157
166
|
.prepare("SELECT key, value FROM cursorDiskKV WHERE key LIKE 'composerData:%'")
|
|
158
167
|
.all();
|
package/dist/types.d.ts
CHANGED
|
@@ -70,6 +70,8 @@ export interface NormalizedSession {
|
|
|
70
70
|
export interface SessionLogAdapter {
|
|
71
71
|
readonly agent: string;
|
|
72
72
|
detect(path: string): boolean;
|
|
73
|
+
/** Derive a stable runtime session id when the transcript itself does not carry one. */
|
|
74
|
+
sessionIdFromPath?(path: string): string | undefined;
|
|
73
75
|
parse(rawChunk: string): NormalizedTurn[];
|
|
74
76
|
parseSession?(rawChunk: string): NormalizedSession;
|
|
75
77
|
parseSessions?(rawChunk: string): NormalizedSession[];
|
|
@@ -79,6 +81,7 @@ export interface JsonlParseStats {
|
|
|
79
81
|
rowsRead: number;
|
|
80
82
|
invalidJson: number;
|
|
81
83
|
}
|
|
84
|
+
export declare function stripUtf8Bom(value: string): string;
|
|
82
85
|
export declare const META_MARKERS: string[];
|
|
83
86
|
export declare function isMetaText(text: string): boolean;
|
|
84
87
|
export declare function parseJsonlLinesWithStats(chunk: string): {
|
package/dist/types.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export function stripUtf8Bom(value) {
|
|
2
|
+
return value.replace(/^\uFEFF/, '');
|
|
3
|
+
}
|
|
1
4
|
export const META_MARKERS = ['HEARTBEAT_OK', 'NO_REPLY', 'NO_RESPONSE_NEEDED', '[META]'];
|
|
2
5
|
export function isMetaText(text) {
|
|
3
6
|
const t = text.trim();
|
|
@@ -7,11 +10,12 @@ export function parseJsonlLinesWithStats(chunk) {
|
|
|
7
10
|
const out = [];
|
|
8
11
|
const stats = { rowsScanned: 0, rowsRead: 0, invalidJson: 0 };
|
|
9
12
|
for (const l of chunk.split('\n')) {
|
|
10
|
-
|
|
13
|
+
const line = stats.rowsScanned === 0 ? stripUtf8Bom(l) : l;
|
|
14
|
+
if (!line.trim())
|
|
11
15
|
continue;
|
|
12
16
|
stats.rowsScanned += 1;
|
|
13
17
|
try {
|
|
14
|
-
const o = JSON.parse(
|
|
18
|
+
const o = JSON.parse(line);
|
|
15
19
|
if (o && typeof o === 'object') {
|
|
16
20
|
out.push(o);
|
|
17
21
|
stats.rowsRead += 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evomap/evolver-runtime-adapters",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "五 runtime 会话日志适配器 (CC/codex/cursor/kiro/opencode)",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
20
|
"dist/",
|
|
21
|
+
"assets/",
|
|
21
22
|
"README.md",
|
|
22
23
|
"package.json"
|
|
23
24
|
]
|