dsh-reference-anything 0.5.0 → 0.5.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/LICENSE +22 -22
- package/NOTICE.md +110 -110
- package/README.md +470 -451
- package/cordis.patch.yml +136 -134
- package/docs/release/0.4.4/README.md +75 -0
- package/{release-notes → docs/release}/0.4.4/features.json +1 -1
- package/docs/release/0.5.0/README.md +148 -0
- package/docs/release/0.5.1/README.md +33 -0
- package/docs/release/0.5.2/README.md +51 -0
- package/docs/release/0.5.2/features.json +29 -0
- package/{release-notes → docs/release}/README.md +12 -6
- package/images/agents/LICENSE +22 -22
- package/images/agents/README.md +7 -3
- package/images/agents/antigravity.svg +1 -1
- package/images/agents/cline.svg +1 -1
- package/images/agents/continue.svg +1 -1
- package/images/agents/copilot.svg +27 -0
- package/images/agents/crush.svg +1 -1
- package/images/agents/doubao.svg +1 -0
- package/images/agents/goose.svg +1 -1
- package/images/agents/omp.svg +1 -0
- package/images/agents/reasonix.svg +5 -5
- package/images/agents/teleagent.svg +1 -1
- package/images/agents/trae.svg +1 -1
- package/images/agents/vibe.svg +1 -1
- package/images/agents/workbuddy.svg +37 -37
- package/images/agents/zed.svg +1 -1
- package/lib/chat-import-compatibility.js +8 -5
- package/lib/client.js +36526 -4
- package/lib/contract.d.ts +4 -0
- package/lib/host.d.ts +2 -2
- package/lib/host.js +4 -1
- package/lib/local-conversation-reader.js +16 -11
- package/lib/render.js +21 -21
- package/lib/store/spec.d.ts +9 -1
- package/lib/tool.js +3 -2
- package/lib/wire.d.ts +13 -1
- package/lib/wire.js +5 -4
- package/locale/en.json +6 -6
- package/locale/zh.json +6 -6
- package/opencli-plugin/chatgpt.js +128 -128
- package/opencli-plugin/claude.js +138 -138
- package/opencli-plugin/common.js +452 -452
- package/opencli-plugin/deepseek.js +155 -155
- package/opencli-plugin/gemini.js +169 -169
- package/opencli-plugin/grok.js +124 -124
- package/opencli-plugin/kimi.js +126 -126
- package/opencli-plugin/opencli-plugin.json +6 -6
- package/opencli-plugin/package.json +8 -8
- package/opencli-plugin/since-guard.js +45 -45
- package/package.json +263 -262
- package/vendor/chat-import-reader/LICENSE +22 -22
- package/vendor/chat-import-reader/README.md +54 -48
- package/vendor/chat-import-reader/availability-worker.mjs +5 -0
- package/vendor/chat-import-reader/parsers.d.mts +6 -6
- package/vendor/chat-import-reader/parsers.mjs +2248 -347
- package/vendor/chat-import-reader/scanners.mjs +1316 -79
- package/vendor/chat-import-reader/upstream-sha256.json +35 -22
- package/release-notes/0.4.4/commands.png +0 -0
- package/release-notes/0.4.4/demos/agent-import.gif +0 -0
- package/release-notes/0.4.4/demos/chat-import-upgrade.gif +0 -0
- package/release-notes/0.4.4/demos/folders.gif +0 -0
- package/release-notes/0.4.4/demos/local-plugins.gif +0 -0
- package/release-notes/0.4.4/demos/shortcuts.gif +0 -0
- package/release-notes/0.4.4/files.png +0 -0
- package/release-notes/0.5.0/demos/agent-import.gif +0 -0
- package/release-notes/0.5.0/demos/chat-import-upgrade.gif +0 -0
- package/release-notes/0.5.0/demos/folders.gif +0 -0
- package/release-notes/0.5.0/demos/local-plugins.gif +0 -0
- package/release-notes/0.5.0/demos/local-references.gif +0 -0
- package/release-notes/0.5.0/demos/shortcuts.gif +0 -0
- /package/{release-notes → docs/release}/0.5.0/features.json +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// Generated by scripts/vendor-chat-import-reader.mjs; see adjacent licenses.
|
|
2
|
-
// .codex-tmp/
|
|
2
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/registry.mjs
|
|
3
3
|
import { homedir as homedir3 } from "node:os";
|
|
4
4
|
|
|
5
|
-
// .codex-tmp/
|
|
5
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/claude.mjs
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
8
|
|
|
9
|
-
// .codex-tmp/
|
|
9
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/inject.mjs
|
|
10
10
|
var INJECT_MARKERS = [
|
|
11
11
|
"<environment_context>",
|
|
12
12
|
"<system-reminder>",
|
|
@@ -60,10 +60,10 @@ function stripUserQueryWrapper(text) {
|
|
|
60
60
|
return parts.join("\n");
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
// .codex-tmp/
|
|
63
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/image.mjs
|
|
64
64
|
var MAX_IMAGE_BASE64_CHARS = 24 * 1024 * 1024;
|
|
65
65
|
|
|
66
|
-
// .codex-tmp/
|
|
66
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/validate.mjs
|
|
67
67
|
var SESSION_EVENT_TYPES = [
|
|
68
68
|
// 本插件自产 / 客户端流事件(宿主词汇表外,见上)
|
|
69
69
|
"session/imported",
|
|
@@ -137,7 +137,7 @@ var SESSION_EVENT_TYPES = [
|
|
|
137
137
|
];
|
|
138
138
|
var SESSION_EVENT_TYPES_SET = new Set(SESSION_EVENT_TYPES);
|
|
139
139
|
|
|
140
|
-
// .codex-tmp/
|
|
140
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/core.mjs
|
|
141
141
|
function parseTimeMs(value, { truncSeconds = false } = {}) {
|
|
142
142
|
if (typeof value === "number") {
|
|
143
143
|
if (!Number.isFinite(value)) return null;
|
|
@@ -154,7 +154,7 @@ function parseTime(value) {
|
|
|
154
154
|
return parseTimeMs(value) ?? Date.now();
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
// .codex-tmp/
|
|
157
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/util.mjs
|
|
158
158
|
import { posix, win32 } from "node:path";
|
|
159
159
|
function joinForPlatform(platform, ...parts) {
|
|
160
160
|
return platform === "win32" ? win32.join(...parts) : posix.join(...parts);
|
|
@@ -187,7 +187,7 @@ function contentText(content, { types = TEXT_BLOCK_TYPES, sep = "\n", skipEmpty
|
|
|
187
187
|
return trim ? text.trim() : text;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
// .codex-tmp/
|
|
190
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/qwen.mjs
|
|
191
191
|
function realWorkspaceDir(directories) {
|
|
192
192
|
if (!Array.isArray(directories)) return null;
|
|
193
193
|
for (const d of directories) {
|
|
@@ -196,7 +196,7 @@ function realWorkspaceDir(directories) {
|
|
|
196
196
|
return null;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
// .codex-tmp/
|
|
199
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/workbuddy.mjs
|
|
200
200
|
function extractWorkbuddyUserQuery(content) {
|
|
201
201
|
const joined = Array.isArray(content) ? contentText(content, { types: null }) : "";
|
|
202
202
|
const m = /<user_query>([\s\S]*?)<\/user_query>/.exec(joined);
|
|
@@ -204,7 +204,7 @@ function extractWorkbuddyUserQuery(content) {
|
|
|
204
204
|
return stripSystemReminders(joined).replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
// .codex-tmp/
|
|
207
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/common.mjs
|
|
208
208
|
var HEAD_MAX_BYTES = 256 * 1024;
|
|
209
209
|
var TAIL_MAX_BYTES = 64 * 1024;
|
|
210
210
|
function pathSegments(p) {
|
|
@@ -331,7 +331,7 @@ async function emitEach(emit, entries) {
|
|
|
331
331
|
for (const e of entries) await emit(e);
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
-
// .codex-tmp/
|
|
334
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/walk.mjs
|
|
335
335
|
var WALK_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
336
336
|
"node_modules",
|
|
337
337
|
".git",
|
|
@@ -373,7 +373,7 @@ async function walkFiles(host2, target, out, match, depth = 0) {
|
|
|
373
373
|
}
|
|
374
374
|
}
|
|
375
375
|
|
|
376
|
-
// .codex-tmp/
|
|
376
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/scan-cache.mjs
|
|
377
377
|
var SCAN_TTL_MS = 3e4;
|
|
378
378
|
function createScanCache({ ttlMs = SCAN_TTL_MS, now = () => Date.now() } = {}) {
|
|
379
379
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -414,7 +414,7 @@ async function probeSource(bm, format, sourcePath, fp, probe, patchHit) {
|
|
|
414
414
|
return entries;
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
-
// .codex-tmp/
|
|
417
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/claude.mjs
|
|
418
418
|
function claudeContextTokens(tailText) {
|
|
419
419
|
let last = null;
|
|
420
420
|
for (const line of String(tailText ?? "").split(/\r?\n/)) {
|
|
@@ -559,7 +559,7 @@ async function findJsonlBySessionId(host2, cliSessionId, projectsRoot) {
|
|
|
559
559
|
return null;
|
|
560
560
|
}
|
|
561
561
|
async function scanQoder(host2, target, { bm, emit }) {
|
|
562
|
-
if (!/\.qoder[\\/]projects([\\/]|$)/i.test(String(target))) return [];
|
|
562
|
+
if (!/\.qoder(?:-cn)?[\\/]projects([\\/]|$)/i.test(String(target))) return [];
|
|
563
563
|
const files = [];
|
|
564
564
|
await walkFiles(host2, target, files, (name) => /\.jsonl$/i.test(name));
|
|
565
565
|
const out = [];
|
|
@@ -577,8 +577,10 @@ async function scanQoder(host2, target, { bm, emit }) {
|
|
|
577
577
|
if (!sessionId || sessionId !== stem) return [];
|
|
578
578
|
const cwd = firstString(recs, (r) => r && r.cwd);
|
|
579
579
|
const createdAt = firstNumber(recs, (r) => r && r.timestamp !== void 0 ? parseTimeValue(r.timestamp) : void 0);
|
|
580
|
-
const
|
|
581
|
-
const
|
|
580
|
+
const whole = st.size <= HEAD_MAX_BYTES;
|
|
581
|
+
const carriers = whole ? recs : [...recs, ...parseJsonlHead(await host2.readTail(file.path, TAIL_MAX_BYTES))];
|
|
582
|
+
const aiTitle = firstString(carriers, (r) => r && r.type === "ai-title" ? r.aiTitle : void 0);
|
|
583
|
+
const lastPrompt = firstString(carriers, (r) => r && r.type === "last-prompt" ? r.lastPrompt : void 0);
|
|
582
584
|
const title = normalizeTitle(aiTitle || lastPrompt) || firstUserTitle(recs, (r) => r && r.type === "user" && r.message && r.message.role === "user" ? contentText2(r.message.content) : "");
|
|
583
585
|
return [makeEntry({
|
|
584
586
|
format: "qoder",
|
|
@@ -724,10 +726,12 @@ var claudeSource = {
|
|
|
724
726
|
};
|
|
725
727
|
var qoderSource = {
|
|
726
728
|
format: "qoder",
|
|
727
|
-
|
|
729
|
+
// Qoder CN 的根与 intl 根并列(缺失的根由 walkFiles 静默落空):两版安装可并存,
|
|
730
|
+
// 会话各自落在自己的根下,一并扫才对得齐用户侧看到的「Qoder 会话」。
|
|
731
|
+
roots: (home) => [join(home, ".qoder", "projects"), join(home, ".qoder-cn", "projects")],
|
|
728
732
|
scan: scanQoder,
|
|
729
733
|
layoutProject: qoderLayoutProject,
|
|
730
|
-
matchFile: (lower) => isJsonl(lower) && /\.qoder[\\/]projects[\\/]/.test(lower)
|
|
734
|
+
matchFile: (lower) => isJsonl(lower) && /\.qoder(?:-cn)?[\\/]projects[\\/]/.test(lower)
|
|
731
735
|
};
|
|
732
736
|
var workbuddySource = {
|
|
733
737
|
format: "workbuddy",
|
|
@@ -743,10 +747,10 @@ var qwenSource = {
|
|
|
743
747
|
matchFile: (lower) => isJsonl(lower) && /\.qwenworkcn[\\/]projects[\\/]/.test(lower)
|
|
744
748
|
};
|
|
745
749
|
|
|
746
|
-
// .codex-tmp/
|
|
750
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/jsonl.mjs
|
|
747
751
|
import { join as join3 } from "node:path";
|
|
748
752
|
|
|
749
|
-
// .codex-tmp/
|
|
753
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/reasonix.mjs
|
|
750
754
|
function reasonixStemTime(stem) {
|
|
751
755
|
const m = String(stem || "").match(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/);
|
|
752
756
|
if (!m) return null;
|
|
@@ -759,7 +763,7 @@ function reasonixStemTime(stem) {
|
|
|
759
763
|
return Number.isNaN(t.getTime()) ? null : t.getTime();
|
|
760
764
|
}
|
|
761
765
|
|
|
762
|
-
// .codex-tmp/
|
|
766
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/codex.mjs
|
|
763
767
|
function codexSubagentMarker(payload) {
|
|
764
768
|
if (!payload || typeof payload !== "object") return null;
|
|
765
769
|
if (payload.thread_source === "subagent") return "thread_source=subagent";
|
|
@@ -780,7 +784,7 @@ function codexUserPrompt(content) {
|
|
|
780
784
|
return parts.join("\n").trim();
|
|
781
785
|
}
|
|
782
786
|
|
|
783
|
-
// .codex-tmp/
|
|
787
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/openclaw.mjs
|
|
784
788
|
function openclawDisplayNames(indexJson) {
|
|
785
789
|
const map = /* @__PURE__ */ new Map();
|
|
786
790
|
let index;
|
|
@@ -799,12 +803,12 @@ function openclawDisplayNames(indexJson) {
|
|
|
799
803
|
return map;
|
|
800
804
|
}
|
|
801
805
|
|
|
802
|
-
// .codex-tmp/
|
|
806
|
+
// .codex-tmp/chat-import-0263/package/lib/cwd-map.mjs
|
|
803
807
|
import { homedir as homedir2 } from "node:os";
|
|
804
808
|
import { join as join2 } from "node:path";
|
|
805
809
|
import { readFile, readdir } from "node:fs/promises";
|
|
806
810
|
|
|
807
|
-
// .codex-tmp/
|
|
811
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/cursor.mjs
|
|
808
812
|
function parseCursorEmbeddedTimestamp(text) {
|
|
809
813
|
const m = String(text ?? "").match(/<timestamp>\s*([^<]+?)\s*<\/timestamp>/i);
|
|
810
814
|
if (!m) return void 0;
|
|
@@ -816,7 +820,7 @@ function stripCursorTitleDecorations(text) {
|
|
|
816
820
|
return String(text ?? "").replace(/<timestamp>[\s\S]*?<\/timestamp>\s*/gi, "").replace(/<\/?user_query>/gi, "").trim();
|
|
817
821
|
}
|
|
818
822
|
|
|
819
|
-
// .codex-tmp/
|
|
823
|
+
// .codex-tmp/chat-import-0263/package/lib/cwd-map.mjs
|
|
820
824
|
var CURSOR_NON_REPO_SLUGS = /* @__PURE__ */ new Set(["empty-window"]);
|
|
821
825
|
function isCursorNonRepoSlug(slug) {
|
|
822
826
|
const s = String(slug ?? "");
|
|
@@ -935,7 +939,7 @@ async function resolveCursorSlugPath(ctx, slug) {
|
|
|
935
939
|
return greedyDecodeCursorSlugPath(ctx, slug);
|
|
936
940
|
}
|
|
937
941
|
|
|
938
|
-
// .codex-tmp/
|
|
942
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/antigravity.mjs
|
|
939
943
|
function unquote(value) {
|
|
940
944
|
if (typeof value !== "string") return value;
|
|
941
945
|
const s = value.trim();
|
|
@@ -966,7 +970,7 @@ function parseAnnotationTitle(raw) {
|
|
|
966
970
|
}
|
|
967
971
|
}
|
|
968
972
|
|
|
969
|
-
// .codex-tmp/
|
|
973
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/opencode.mjs
|
|
970
974
|
var OPENCODE_TOOL_ALIASES = {
|
|
971
975
|
websearch: "web_search",
|
|
972
976
|
webfetch: "web_fetch",
|
|
@@ -978,7 +982,7 @@ var DSH_TO_OPENCODE = Object.fromEntries(
|
|
|
978
982
|
Object.entries(OPENCODE_TOOL_ALIASES).map(([local, dsh]) => [dsh, local])
|
|
979
983
|
);
|
|
980
984
|
|
|
981
|
-
// .codex-tmp/
|
|
985
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/trae.mjs
|
|
982
986
|
var MESSAGE_TEXT_KEYS = ["content", "text", "message", "body", "prompt", "response", "output", "result"];
|
|
983
987
|
var SESSION_MESSAGE_KEYS = ["messages", "chatMessages", "history", "messageList", "entries"];
|
|
984
988
|
var SESSION_ID_KEYS = ["sessionId", "id", "uuid", "session_id"];
|
|
@@ -1113,12 +1117,12 @@ function normalizeTraeSession(session, index = 0) {
|
|
|
1113
1117
|
return normalized;
|
|
1114
1118
|
}
|
|
1115
1119
|
|
|
1116
|
-
// .codex-tmp/
|
|
1120
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/hermes.mjs
|
|
1117
1121
|
function parseHermesTime(value) {
|
|
1118
1122
|
return parseTimeMs(value, { truncSeconds: true }) ?? void 0;
|
|
1119
1123
|
}
|
|
1120
1124
|
|
|
1121
|
-
// .codex-tmp/
|
|
1125
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/continue.mjs
|
|
1122
1126
|
function indexTime(v) {
|
|
1123
1127
|
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
1124
1128
|
if (typeof v === "string") {
|
|
@@ -1152,7 +1156,7 @@ function readContinueIndex(raw) {
|
|
|
1152
1156
|
return out;
|
|
1153
1157
|
}
|
|
1154
1158
|
|
|
1155
|
-
// .codex-tmp/
|
|
1159
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/cline.mjs
|
|
1156
1160
|
function clineLegacyTaskHistoryPath(globalStorageDir) {
|
|
1157
1161
|
const sep = String(globalStorageDir).includes("\\") ? "\\" : "/";
|
|
1158
1162
|
return String(globalStorageDir).replace(/[\\/]+$/, "") + sep + "state" + sep + "taskHistory.json";
|
|
@@ -1206,7 +1210,7 @@ function readClineManifest(raw) {
|
|
|
1206
1210
|
return { title, cwd, startedAt };
|
|
1207
1211
|
}
|
|
1208
1212
|
|
|
1209
|
-
// .codex-tmp/
|
|
1213
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/goose.mjs
|
|
1210
1214
|
function gooseDataDir(home, env = process.env, platform = process.platform) {
|
|
1211
1215
|
const root = env.GOOSE_PATH_ROOT;
|
|
1212
1216
|
if (root && isAbsoluteLike(root)) return joinForPlatform(platform, String(root), "data");
|
|
@@ -1218,7 +1222,7 @@ function gooseSessionsDir(home, env = process.env, platform = process.platform)
|
|
|
1218
1222
|
return joinForPlatform(platform, gooseDataDir(home, env, platform), "sessions");
|
|
1219
1223
|
}
|
|
1220
1224
|
|
|
1221
|
-
// .codex-tmp/
|
|
1225
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/zed.mjs
|
|
1222
1226
|
function zedDataDir(home, env = process.env, platform = process.platform) {
|
|
1223
1227
|
if (platform === "win32" && env.LOCALAPPDATA) return joinForPlatform(platform, String(env.LOCALAPPDATA), "Zed");
|
|
1224
1228
|
if (platform === "darwin") return joinForPlatform(platform, String(home), "Library", "Application Support", "Zed");
|
|
@@ -1239,7 +1243,7 @@ function zedFolderPaths(folderPaths, folderPathsOrder) {
|
|
|
1239
1243
|
return order.map((i) => paths[i]);
|
|
1240
1244
|
}
|
|
1241
1245
|
|
|
1242
|
-
// .codex-tmp/
|
|
1246
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/crush.mjs
|
|
1243
1247
|
function crushUserDataDir(home, env = process.env, platform = process.platform) {
|
|
1244
1248
|
const override = env.CRUSH_GLOBAL_DATA;
|
|
1245
1249
|
if (override && isAbsoluteLike(override)) return String(override);
|
|
@@ -1274,21 +1278,242 @@ function parseCrushProjects(raw) {
|
|
|
1274
1278
|
return out;
|
|
1275
1279
|
}
|
|
1276
1280
|
|
|
1277
|
-
// .codex-tmp/
|
|
1281
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/vibe.mjs
|
|
1278
1282
|
function parseVibeTime(value) {
|
|
1279
1283
|
return parseTimeMs(value, { truncSeconds: true }) ?? void 0;
|
|
1280
1284
|
}
|
|
1281
1285
|
|
|
1282
|
-
// .codex-tmp/
|
|
1286
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/doubao.mjs
|
|
1287
|
+
var DOUBAO_TEXT_BLOCK = 1e4;
|
|
1288
|
+
var DOUBAO_PROTOCOL_KEY = "default-chat-im-protocol-store";
|
|
1289
|
+
var DOUBAO_LIST_SCHEMA_PREFIX = "conversation-list-data-";
|
|
1290
|
+
function doubaoTime(value) {
|
|
1291
|
+
if (typeof value === "number") return parseTimeMs(value);
|
|
1292
|
+
if (typeof value === "string" && value.trim()) {
|
|
1293
|
+
const numeric = Number(value);
|
|
1294
|
+
if (Number.isFinite(numeric)) return parseTimeMs(numeric);
|
|
1295
|
+
return parseTimeMs(value);
|
|
1296
|
+
}
|
|
1297
|
+
return null;
|
|
1298
|
+
}
|
|
1299
|
+
function textOfBlocks(blocks, stats) {
|
|
1300
|
+
const out = [];
|
|
1301
|
+
for (const block of Array.isArray(blocks) ? blocks : []) {
|
|
1302
|
+
if (!block || typeof block !== "object") continue;
|
|
1303
|
+
if (block.block_type !== DOUBAO_TEXT_BLOCK) {
|
|
1304
|
+
stats.skippedBlocks++;
|
|
1305
|
+
continue;
|
|
1306
|
+
}
|
|
1307
|
+
const text = block.content && block.content.text_block && block.content.text_block.text;
|
|
1308
|
+
if (typeof text === "string" && text) out.push(text);
|
|
1309
|
+
else stats.emptyBlocks++;
|
|
1310
|
+
}
|
|
1311
|
+
return out.join("\n");
|
|
1312
|
+
}
|
|
1313
|
+
function normalizeDoubaoTask(taskId, task, stats) {
|
|
1314
|
+
if (!task || typeof task !== "object") return null;
|
|
1315
|
+
const sync = task.requestQuery && task.requestQuery.syncTask;
|
|
1316
|
+
const meta = sync && sync.client_meta;
|
|
1317
|
+
const conversationId = meta && typeof meta.conversation_id === "string" && meta.conversation_id ? meta.conversation_id : null;
|
|
1318
|
+
if (!conversationId) return null;
|
|
1319
|
+
const prompt = textOfBlocks(
|
|
1320
|
+
(Array.isArray(sync.messages) ? sync.messages : []).flatMap((m) => m && Array.isArray(m.content_block) ? m.content_block : []),
|
|
1321
|
+
stats
|
|
1322
|
+
);
|
|
1323
|
+
const replies = [];
|
|
1324
|
+
let replyTime = null;
|
|
1325
|
+
for (const id of Object.keys(task.receivedMessages ?? {})) {
|
|
1326
|
+
const received = task.receivedMessages[id];
|
|
1327
|
+
const extra = received && received.extra;
|
|
1328
|
+
if (!extra) continue;
|
|
1329
|
+
const text = textOfBlocks(extra.content_blocks_v2, stats);
|
|
1330
|
+
if (text) replies.push(text);
|
|
1331
|
+
if (replyTime === null) replyTime = doubaoTime(extra.create_time);
|
|
1332
|
+
}
|
|
1333
|
+
const reply = replies.join("\n");
|
|
1334
|
+
if (!prompt && !reply) return null;
|
|
1335
|
+
const option = sync && sync.option;
|
|
1336
|
+
return {
|
|
1337
|
+
conversationId,
|
|
1338
|
+
taskId: typeof taskId === "string" ? taskId : String(taskId),
|
|
1339
|
+
prompt,
|
|
1340
|
+
reply,
|
|
1341
|
+
promptTime: doubaoTime(option && option.create_time_ms) ?? doubaoTime(task.createTime),
|
|
1342
|
+
replyTime
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
function collectDoubaoTasks(records, stats) {
|
|
1346
|
+
const best = /* @__PURE__ */ new Map();
|
|
1347
|
+
let restarted = 0;
|
|
1348
|
+
for (const record of records) {
|
|
1349
|
+
const snapshots = Array.isArray(record && record.versions) ? record.versions : [record && record.value];
|
|
1350
|
+
for (const snapshot of snapshots) {
|
|
1351
|
+
const tasks = snapshot && snapshot.state && snapshot.state.mainTaskDataMap;
|
|
1352
|
+
if (!tasks || typeof tasks !== "object") continue;
|
|
1353
|
+
for (const [taskId, task] of Object.entries(tasks)) {
|
|
1354
|
+
const normalized = normalizeDoubaoTask(taskId, task, stats);
|
|
1355
|
+
if (!normalized) continue;
|
|
1356
|
+
const key = normalized.taskId;
|
|
1357
|
+
const prev = best.get(key);
|
|
1358
|
+
if (!prev) {
|
|
1359
|
+
best.set(key, normalized);
|
|
1360
|
+
continue;
|
|
1361
|
+
}
|
|
1362
|
+
if (normalized.reply.length > prev.reply.length) {
|
|
1363
|
+
if (prev.reply && normalized.reply && !normalized.reply.startsWith(prev.reply)) restarted++;
|
|
1364
|
+
best.set(key, { ...normalized, prompt: normalized.prompt || prev.prompt });
|
|
1365
|
+
} else if (normalized.prompt && !prev.prompt) {
|
|
1366
|
+
prev.prompt = normalized.prompt;
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
return { turns: [...best.values()], restarted };
|
|
1372
|
+
}
|
|
1373
|
+
function collectDoubaoConversations(records) {
|
|
1374
|
+
const conversations = /* @__PURE__ */ new Map();
|
|
1375
|
+
for (const record of records) {
|
|
1376
|
+
const value = record && record.value;
|
|
1377
|
+
if (!value || typeof value !== "object") continue;
|
|
1378
|
+
if (typeof value.schema !== "string" || !value.schema.startsWith(DOUBAO_LIST_SCHEMA_PREFIX)) continue;
|
|
1379
|
+
const list = value.data && Array.isArray(value.data.conversations) ? value.data.conversations : [];
|
|
1380
|
+
for (const item of list) {
|
|
1381
|
+
if (!item || typeof item !== "object") continue;
|
|
1382
|
+
const id = typeof item.conversation_id === "string" && item.conversation_id ? item.conversation_id : null;
|
|
1383
|
+
if (!id) continue;
|
|
1384
|
+
const title = typeof item.name === "string" ? item.name.trim() : "";
|
|
1385
|
+
const createdAt = doubaoTime(item.create_time);
|
|
1386
|
+
const updatedAt = doubaoTime(item.update_time);
|
|
1387
|
+
const prev = conversations.get(id);
|
|
1388
|
+
if (!prev) {
|
|
1389
|
+
conversations.set(id, { id, title, createdAt, updatedAt });
|
|
1390
|
+
continue;
|
|
1391
|
+
}
|
|
1392
|
+
if (!prev.title && title) prev.title = title;
|
|
1393
|
+
if (prev.createdAt === null && createdAt !== null) prev.createdAt = createdAt;
|
|
1394
|
+
else if (createdAt !== null && prev.createdAt !== null && createdAt < prev.createdAt) prev.createdAt = createdAt;
|
|
1395
|
+
if (updatedAt !== null && (prev.updatedAt === null || updatedAt > prev.updatedAt)) prev.updatedAt = updatedAt;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
return conversations;
|
|
1399
|
+
}
|
|
1400
|
+
function extractDoubaoSessions(db) {
|
|
1401
|
+
const stats = { skippedBlocks: 0, emptyBlocks: 0, restarted: 0, emptyConversations: 0, orphanConversations: 0 };
|
|
1402
|
+
const records = Array.isArray(db && db.records) ? db.records : [];
|
|
1403
|
+
const conversations = collectDoubaoConversations(records);
|
|
1404
|
+
const protocolRecords = records.filter((r) => r && r.key === DOUBAO_PROTOCOL_KEY);
|
|
1405
|
+
const { turns, restarted } = collectDoubaoTasks(protocolRecords, stats);
|
|
1406
|
+
stats.restarted = restarted;
|
|
1407
|
+
const byConversation = /* @__PURE__ */ new Map();
|
|
1408
|
+
for (const turn of turns) {
|
|
1409
|
+
const list = byConversation.get(turn.conversationId) ?? [];
|
|
1410
|
+
list.push(turn);
|
|
1411
|
+
byConversation.set(turn.conversationId, list);
|
|
1412
|
+
}
|
|
1413
|
+
const sessions = [];
|
|
1414
|
+
for (const [conversationId, list] of byConversation) {
|
|
1415
|
+
const usable = list.filter((t) => t.prompt || t.reply);
|
|
1416
|
+
if (usable.length === 0) {
|
|
1417
|
+
stats.emptyConversations++;
|
|
1418
|
+
continue;
|
|
1419
|
+
}
|
|
1420
|
+
usable.sort((a, b) => (a.promptTime ?? a.replyTime ?? Number.MAX_SAFE_INTEGER) - (b.promptTime ?? b.replyTime ?? Number.MAX_SAFE_INTEGER));
|
|
1421
|
+
const meta = conversations.get(conversationId);
|
|
1422
|
+
if (!meta) stats.orphanConversations++;
|
|
1423
|
+
const times = usable.flatMap((t) => [t.promptTime, t.replyTime]).filter((t) => t !== null && t !== void 0);
|
|
1424
|
+
sessions.push({
|
|
1425
|
+
id: conversationId,
|
|
1426
|
+
title: meta && meta.title ? meta.title : "",
|
|
1427
|
+
createdAt: meta && meta.createdAt !== null ? meta.createdAt : times.length ? Math.min(...times) : null,
|
|
1428
|
+
updatedAt: meta && meta.updatedAt !== null ? meta.updatedAt : times.length ? Math.max(...times) : null,
|
|
1429
|
+
turns: usable
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
sessions.sort((a, b) => (b.updatedAt ?? b.createdAt ?? 0) - (a.updatedAt ?? a.createdAt ?? 0));
|
|
1433
|
+
return { sessions, stats };
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/copilot-vscode.mjs
|
|
1437
|
+
import { fileURLToPath } from "node:url";
|
|
1438
|
+
function readCopilotVscodeSession(raw) {
|
|
1439
|
+
let session;
|
|
1440
|
+
try {
|
|
1441
|
+
session = JSON.parse(raw);
|
|
1442
|
+
} catch {
|
|
1443
|
+
return null;
|
|
1444
|
+
}
|
|
1445
|
+
return session && session.version === 3 && typeof session.sessionId === "string" && session.sessionId.trim() && Array.isArray(session.requests) ? session : null;
|
|
1446
|
+
}
|
|
1447
|
+
function copilotVscodeCwd(value) {
|
|
1448
|
+
if (typeof value !== "string" || !value) return null;
|
|
1449
|
+
if (isAbsoluteLike(value)) return value;
|
|
1450
|
+
try {
|
|
1451
|
+
const uri = new URL(value);
|
|
1452
|
+
if (uri.protocol !== "file:") return null;
|
|
1453
|
+
const windows = /^\/[a-z]:/i.test(decodeURIComponent(uri.pathname)) || !!(uri.hostname && uri.hostname !== "localhost");
|
|
1454
|
+
return fileURLToPath(uri, { windows });
|
|
1455
|
+
} catch {
|
|
1456
|
+
return null;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
function promptText(message) {
|
|
1460
|
+
if (typeof message === "string") return message;
|
|
1461
|
+
if (!message || typeof message !== "object") return "";
|
|
1462
|
+
return typeof message.text === "string" ? message.text : contentText(message.parts, { types: null, sep: "", skipEmpty: true });
|
|
1463
|
+
}
|
|
1464
|
+
function copilotVscodeMetadata(session) {
|
|
1465
|
+
const times = [];
|
|
1466
|
+
for (const request of session.requests) {
|
|
1467
|
+
if (!request || typeof request !== "object") continue;
|
|
1468
|
+
times.push(request.timestamp, request.responseTimestamp);
|
|
1469
|
+
for (const part of Array.isArray(request.response) ? request.response : []) {
|
|
1470
|
+
if (part && typeof part === "object") times.push(part.startedAt, part.completedAt);
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
const valid = [session.creationDate, session.lastMessageDate, ...times].map((v) => parseTimeMs(v)).filter((v) => v !== null);
|
|
1474
|
+
return {
|
|
1475
|
+
id: session.sessionId,
|
|
1476
|
+
title: normalizeTitle(typeof session.customTitle === "string" && session.customTitle.trim() ? session.customTitle : promptText(session.requests.find((r) => r?.message)?.message)),
|
|
1477
|
+
cwd: copilotVscodeCwd(session.workingDirectory),
|
|
1478
|
+
createdAt: parseTimeMs(session.creationDate) ?? valid[0],
|
|
1479
|
+
lastActiveAt: valid.length ? valid.reduce((latest, time) => Math.max(latest, time)) : void 0
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
// .codex-tmp/chat-import-0263/package/lib/convert/copilot-cli.mjs
|
|
1484
|
+
function copilotCliHeadMeta(recs) {
|
|
1485
|
+
const start = recs.find((r) => r && r.type === "session.start" && r.data && typeof r.data === "object");
|
|
1486
|
+
if (!start) return null;
|
|
1487
|
+
const data = start.data;
|
|
1488
|
+
const context2 = data.context && typeof data.context === "object" ? data.context : {};
|
|
1489
|
+
let title = null;
|
|
1490
|
+
for (const rec of recs) {
|
|
1491
|
+
if (!rec || rec.type !== "user.message" || !rec.data || typeof rec.data !== "object") continue;
|
|
1492
|
+
const text = typeof rec.data.content === "string" ? rec.data.content.trim() : "";
|
|
1493
|
+
if (text) {
|
|
1494
|
+
title = text;
|
|
1495
|
+
break;
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
return {
|
|
1499
|
+
id: typeof data.sessionId === "string" && data.sessionId ? data.sessionId : null,
|
|
1500
|
+
cwd: typeof context2.cwd === "string" && context2.cwd ? context2.cwd : null,
|
|
1501
|
+
createdAt: parseTimeMs(start.timestamp) ?? parseTimeMs(data.startTime),
|
|
1502
|
+
model: typeof data.selectedModel === "string" && data.selectedModel ? data.selectedModel : null,
|
|
1503
|
+
title
|
|
1504
|
+
};
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
// .codex-tmp/chat-import-0263/package/lib/ignore.mjs
|
|
1283
1508
|
var IGNORE_VERSION = 1;
|
|
1284
|
-
var IGNORE_REASONS = Object.freeze(["archived", "retracted", "workspace-deleted"]);
|
|
1509
|
+
var IGNORE_REASONS = Object.freeze(["archived", "retracted", "workspace-deleted", "hidden"]);
|
|
1285
1510
|
function emptyIgnores() {
|
|
1286
1511
|
return { version: IGNORE_VERSION, sources: {}, workspaces: {} };
|
|
1287
1512
|
}
|
|
1288
1513
|
var lastIgnoreSnapshot = emptyIgnores();
|
|
1289
1514
|
var writeChain = Promise.resolve();
|
|
1290
1515
|
|
|
1291
|
-
// .codex-tmp/
|
|
1516
|
+
// .codex-tmp/chat-import-0263/package/lib/host-session.mjs
|
|
1292
1517
|
var SYSTEM_PROMPT_PLUGIN = "@deepseek-ai/dsh-system-prompt";
|
|
1293
1518
|
var RENAMED_PRODUCERS = {
|
|
1294
1519
|
compact: "compact-checkpoint",
|
|
@@ -1298,13 +1523,16 @@ var RENAMED_PRODUCERS = {
|
|
|
1298
1523
|
[SYSTEM_PROMPT_PLUGIN]: "runtime-context"
|
|
1299
1524
|
};
|
|
1300
1525
|
|
|
1301
|
-
// .codex-tmp/
|
|
1526
|
+
// .codex-tmp/chat-import-0263/package/lib/imports.mjs
|
|
1302
1527
|
var writeChain2 = Promise.resolve();
|
|
1303
1528
|
|
|
1304
1529
|
// vendor/chat-import-reader/conversation-content.mjs
|
|
1305
1530
|
var READ_CONTENT = Symbol("readConversation");
|
|
1306
1531
|
|
|
1307
|
-
// .codex-tmp/
|
|
1532
|
+
// .codex-tmp/chat-import-0263/package/lib/import-core.mjs
|
|
1533
|
+
var DESTINATION_FINGERPRINT_KEYS = Object.freeze(["workspaceMode", "workspaceDir", "restamp"]);
|
|
1534
|
+
|
|
1535
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/codex.mjs
|
|
1308
1536
|
function codexThreadIdFromName(name) {
|
|
1309
1537
|
const m = String(name).match(/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/);
|
|
1310
1538
|
return m ? m[0] : void 0;
|
|
@@ -1339,7 +1567,7 @@ function groupCodexThreads(files) {
|
|
|
1339
1567
|
return groups;
|
|
1340
1568
|
}
|
|
1341
1569
|
|
|
1342
|
-
// .codex-tmp/
|
|
1570
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/jsonl.mjs
|
|
1343
1571
|
async function scanCodex(host2, target, { bm, emit }) {
|
|
1344
1572
|
const files = [];
|
|
1345
1573
|
await walkFiles(host2, target, files, (name) => /\.jsonl$/i.test(name));
|
|
@@ -1651,6 +1879,53 @@ async function scanPi(host2, target, { bm, emit }) {
|
|
|
1651
1879
|
}
|
|
1652
1880
|
return out;
|
|
1653
1881
|
}
|
|
1882
|
+
async function scanOmp(host2, target, { bm, emit }) {
|
|
1883
|
+
const files = [];
|
|
1884
|
+
await walkFiles(host2, target, files, (name) => /\.jsonl$/i.test(name));
|
|
1885
|
+
const out = [];
|
|
1886
|
+
for (const file of files) {
|
|
1887
|
+
const st = await host2.stat(file.path);
|
|
1888
|
+
if (!st) continue;
|
|
1889
|
+
const entries = await probeSource(bm, "omp", file.path, fileFingerprint(st), async () => {
|
|
1890
|
+
const head = await host2.readHead(file.path, HEAD_MAX_BYTES);
|
|
1891
|
+
if (head === null || head === "") return [];
|
|
1892
|
+
const recs = parseJsonlHead(head);
|
|
1893
|
+
const header = recs.find((r) => r && r.type === "session" && (typeof r.version === "number" || typeof r.id === "string"));
|
|
1894
|
+
if (!header) return [];
|
|
1895
|
+
const base = basenameOf(file.name).replace(/\.jsonl$/i, "");
|
|
1896
|
+
const stemId = base.includes("_") ? base.slice(base.indexOf("_") + 1) : base;
|
|
1897
|
+
const sessionId = typeof header.id === "string" && header.id ? header.id : stemId;
|
|
1898
|
+
let name = "";
|
|
1899
|
+
const slot = recs.find((r) => r && r.type === "title" && typeof r.title === "string" && r.title.trim());
|
|
1900
|
+
if (slot) name = slot.title.trim();
|
|
1901
|
+
else if (typeof header.title === "string" && header.title.trim()) name = header.title.trim();
|
|
1902
|
+
else {
|
|
1903
|
+
for (let i = recs.length - 1; i >= 0; i--) {
|
|
1904
|
+
const r = recs[i];
|
|
1905
|
+
if (r && r.type === "title_change" && typeof r.title === "string" && r.title.trim()) {
|
|
1906
|
+
name = r.title.trim();
|
|
1907
|
+
break;
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
const title = normalizeTitle(name) || firstUserTitle(recs, (r) => r && r.type === "message" && r.message && r.message.role === "user" ? contentText2(r.message.content) : "");
|
|
1912
|
+
const cwd = typeof header.cwd === "string" ? header.cwd : void 0;
|
|
1913
|
+
return [makeEntry({
|
|
1914
|
+
format: "omp",
|
|
1915
|
+
sessionId,
|
|
1916
|
+
title,
|
|
1917
|
+
project: projectFromRecord(cwd, () => null),
|
|
1918
|
+
createdAt: parseTimeValue(header.timestamp),
|
|
1919
|
+
lastActiveAt: st.mtimeMs,
|
|
1920
|
+
sourcePath: file.path,
|
|
1921
|
+
cwd
|
|
1922
|
+
})];
|
|
1923
|
+
});
|
|
1924
|
+
out.push(...entries);
|
|
1925
|
+
await emitEach(emit, entries);
|
|
1926
|
+
}
|
|
1927
|
+
return out;
|
|
1928
|
+
}
|
|
1654
1929
|
function codexLayoutProject(sourcePath) {
|
|
1655
1930
|
const m = slashPath(sourcePath).match(/\/sessions\/(\d{4})\/(\d{2})\//);
|
|
1656
1931
|
return m ? m[1] + "/" + m[2] : null;
|
|
@@ -1712,8 +1987,15 @@ var piSource = {
|
|
|
1712
1987
|
// 无路径特征时不进通用 JSONL 回退(会话头签名与 hermes/openclaw 的 session 头相近)
|
|
1713
1988
|
matchFile: (lower) => isJsonl2(lower) && /\.pi[\\/]agent[\\/]sessions[\\/]/.test(lower)
|
|
1714
1989
|
};
|
|
1990
|
+
var ompSource = {
|
|
1991
|
+
format: "omp",
|
|
1992
|
+
roots: (home) => join3(home, ".omp", "agent", "sessions"),
|
|
1993
|
+
scan: scanOmp,
|
|
1994
|
+
// 同上:头签名与 pi/hermes/openclaw 相近,只认路径特征(.omp/agent/sessions/)
|
|
1995
|
+
matchFile: (lower) => isJsonl2(lower) && /\.omp[\\/]agent[\\/]sessions[\\/]/.test(lower)
|
|
1996
|
+
};
|
|
1715
1997
|
|
|
1716
|
-
// .codex-tmp/
|
|
1998
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/gemini.mjs
|
|
1717
1999
|
import { join as join4 } from "node:path";
|
|
1718
2000
|
async function scanGemini(host2, target, { bm, emit }) {
|
|
1719
2001
|
const files = [];
|
|
@@ -1847,11 +2129,11 @@ var antigravitySource = {
|
|
|
1847
2129
|
layoutProject: antigravityLayoutProject
|
|
1848
2130
|
};
|
|
1849
2131
|
|
|
1850
|
-
// .codex-tmp/
|
|
2132
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/trae.mjs
|
|
1851
2133
|
import { join as join5 } from "node:path";
|
|
1852
2134
|
import { TextDecoder } from "node:util";
|
|
1853
2135
|
|
|
1854
|
-
// .codex-tmp/
|
|
2136
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/sqlite.mjs
|
|
1855
2137
|
var DatabaseSync = null;
|
|
1856
2138
|
function loadDatabaseSync() {
|
|
1857
2139
|
if (DatabaseSync) return DatabaseSync;
|
|
@@ -1912,7 +2194,7 @@ function hasTable(db, name) {
|
|
|
1912
2194
|
return db.prepare("SELECT COUNT(*) AS n FROM sqlite_master WHERE type = 'table' AND name = ?").get(name).n > 0;
|
|
1913
2195
|
}
|
|
1914
2196
|
|
|
1915
|
-
// .codex-tmp/
|
|
2197
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/opencode.mjs
|
|
1916
2198
|
function opencodeSchemaGeneration(db) {
|
|
1917
2199
|
const names = tableNames(db);
|
|
1918
2200
|
if (names.has("session_v2")) return "v2";
|
|
@@ -1951,7 +2233,7 @@ function readOpencodeDbSummaries(dbPath, options = {}) {
|
|
|
1951
2233
|
});
|
|
1952
2234
|
}
|
|
1953
2235
|
|
|
1954
|
-
// .codex-tmp/
|
|
2236
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/trae.mjs
|
|
1955
2237
|
var TRAE_DB_NAME = "state.vscdb";
|
|
1956
2238
|
var TRAE_STORAGE_KEY = "memento/icube-ai-agent-storage";
|
|
1957
2239
|
var TRAE_FALLBACK_KEYS = [
|
|
@@ -1960,6 +2242,10 @@ var TRAE_FALLBACK_KEYS = [
|
|
|
1960
2242
|
"memento/icube-ai-chat-storage-7467774676505887760",
|
|
1961
2243
|
"memento/icube-ai-ng-chat-storage-7467774676505887760"
|
|
1962
2244
|
];
|
|
2245
|
+
var TRAE_KEY_LIKE = [
|
|
2246
|
+
"%icube-ai-chat-storage-%",
|
|
2247
|
+
"%icube-ai-ng-chat-storage-%"
|
|
2248
|
+
];
|
|
1963
2249
|
function decodeSqlValue(value) {
|
|
1964
2250
|
if (typeof value === "string") return value;
|
|
1965
2251
|
if (value instanceof Uint8Array) return new TextDecoder().decode(value);
|
|
@@ -1984,6 +2270,12 @@ function sessionRows(db) {
|
|
|
1984
2270
|
}
|
|
1985
2271
|
const statement = db.prepare("SELECT value FROM ItemTable WHERE key = ?");
|
|
1986
2272
|
const keys = [TRAE_STORAGE_KEY, ...TRAE_FALLBACK_KEYS];
|
|
2273
|
+
const family = db.prepare(
|
|
2274
|
+
"SELECT key FROM ItemTable WHERE " + TRAE_KEY_LIKE.map(() => "key LIKE ?").join(" OR ")
|
|
2275
|
+
);
|
|
2276
|
+
for (const row of family.all(...TRAE_KEY_LIKE)) {
|
|
2277
|
+
if (typeof row?.key === "string" && !keys.includes(row.key)) keys.push(row.key);
|
|
2278
|
+
}
|
|
1987
2279
|
const seen = /* @__PURE__ */ new Set();
|
|
1988
2280
|
const sessions = [];
|
|
1989
2281
|
let entries = 0;
|
|
@@ -2075,7 +2367,7 @@ async function listTraeDatabases(host2, target) {
|
|
|
2075
2367
|
return found;
|
|
2076
2368
|
}
|
|
2077
2369
|
|
|
2078
|
-
// .codex-tmp/
|
|
2370
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/sqlite.mjs
|
|
2079
2371
|
import { join as join6 } from "node:path";
|
|
2080
2372
|
function traeUserDataDirs(home, env = process.env) {
|
|
2081
2373
|
const names = ["Trae", "Trae CN", "TRAE SOLO CN", "TRAE SOLO"];
|
|
@@ -2396,7 +2688,7 @@ var hermesSource = {
|
|
|
2396
2688
|
fileFallback: ["jsonl", "db"]
|
|
2397
2689
|
};
|
|
2398
2690
|
|
|
2399
|
-
// .codex-tmp/
|
|
2691
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/cline.mjs
|
|
2400
2692
|
import { join as join7 } from "node:path";
|
|
2401
2693
|
function clineDataDir(home, env) {
|
|
2402
2694
|
if (env.CLINE_DATA_DIR) return env.CLINE_DATA_DIR;
|
|
@@ -2601,11 +2893,11 @@ var clineSource = {
|
|
|
2601
2893
|
}
|
|
2602
2894
|
};
|
|
2603
2895
|
|
|
2604
|
-
// .codex-tmp/
|
|
2896
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/session-dirs.mjs
|
|
2605
2897
|
import { join as join9 } from "node:path";
|
|
2606
2898
|
import { createHash } from "node:crypto";
|
|
2607
2899
|
|
|
2608
|
-
// .codex-tmp/
|
|
2900
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/vibe.mjs
|
|
2609
2901
|
import { join as join8 } from "node:path";
|
|
2610
2902
|
var VIBE_SESSION_FILE = "messages.jsonl";
|
|
2611
2903
|
var VIBE_META_FILE = "meta.json";
|
|
@@ -2683,7 +2975,7 @@ async function readVibeSessionSummary(host2, sessionDir) {
|
|
|
2683
2975
|
};
|
|
2684
2976
|
}
|
|
2685
2977
|
|
|
2686
|
-
// .codex-tmp/
|
|
2978
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/session-dirs.mjs
|
|
2687
2979
|
function kimiContextTokens(tailText) {
|
|
2688
2980
|
let last = null;
|
|
2689
2981
|
for (const line of String(tailText ?? "").split(/\r?\n/)) {
|
|
@@ -2972,14 +3264,832 @@ var vibeSource = {
|
|
|
2972
3264
|
matchFile: (lower) => lower.endsWith(".jsonl") && /(\.vibe[\\/]logs[\\/]session|messages\.jsonl$)/.test(lower)
|
|
2973
3265
|
};
|
|
2974
3266
|
|
|
2975
|
-
// .codex-tmp/
|
|
3267
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/indexeddb.mjs
|
|
3268
|
+
import { join as join12 } from "node:path";
|
|
3269
|
+
|
|
3270
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/doubao.mjs
|
|
3271
|
+
import { join as join11 } from "node:path";
|
|
3272
|
+
|
|
3273
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/chromium-indexeddb.mjs
|
|
3274
|
+
import { lstatSync } from "node:fs";
|
|
3275
|
+
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
2976
3276
|
import { join as join10 } from "node:path";
|
|
3277
|
+
var BLOCK_SIZE = 32768;
|
|
3278
|
+
var SNAPPY_MAX_OUTPUT = 512 * 1024 * 1024;
|
|
3279
|
+
var CRC_TABLE = (() => {
|
|
3280
|
+
const table = new Uint32Array(256);
|
|
3281
|
+
for (let i = 0; i < 256; i++) {
|
|
3282
|
+
let c = i;
|
|
3283
|
+
for (let k = 0; k < 8; k++) c = c & 1 ? 2197175160 ^ c >>> 1 : c >>> 1;
|
|
3284
|
+
table[i] = c >>> 0;
|
|
3285
|
+
}
|
|
3286
|
+
return table;
|
|
3287
|
+
})();
|
|
3288
|
+
function crc32c(buf) {
|
|
3289
|
+
let c = 4294967295;
|
|
3290
|
+
for (let i = 0; i < buf.length; i++) c = CRC_TABLE[(c ^ buf[i]) & 255] ^ c >>> 8;
|
|
3291
|
+
return (c ^ 4294967295) >>> 0;
|
|
3292
|
+
}
|
|
3293
|
+
function unmaskCrc(masked) {
|
|
3294
|
+
const rot = masked - 2726488792 >>> 0;
|
|
3295
|
+
return (rot >>> 17 | rot << 15) >>> 0;
|
|
3296
|
+
}
|
|
3297
|
+
function snappyUncompress(input) {
|
|
3298
|
+
let pos = 0;
|
|
3299
|
+
let outLen = 0;
|
|
3300
|
+
let shift = 0;
|
|
3301
|
+
for (; ; ) {
|
|
3302
|
+
if (pos >= input.length) throw new Error("snappy: \u957F\u5EA6\u524D\u7F00\u622A\u65AD");
|
|
3303
|
+
const b = input[pos++];
|
|
3304
|
+
outLen += (b & 127) * 2 ** shift;
|
|
3305
|
+
if (b < 128) break;
|
|
3306
|
+
shift += 7;
|
|
3307
|
+
if (shift > 35) throw new Error("snappy: \u957F\u5EA6\u524D\u7F00\u8FC7\u957F");
|
|
3308
|
+
}
|
|
3309
|
+
if (outLen > SNAPPY_MAX_OUTPUT) throw new Error("snappy: \u89E3\u538B\u957F\u5EA6\u5F02\u5E38 " + outLen);
|
|
3310
|
+
const out = Buffer.alloc(outLen);
|
|
3311
|
+
let opos = 0;
|
|
3312
|
+
while (pos < input.length && opos < outLen) {
|
|
3313
|
+
const tag = input[pos++];
|
|
3314
|
+
const type = tag & 3;
|
|
3315
|
+
if (type === 0) {
|
|
3316
|
+
let len = tag >> 2;
|
|
3317
|
+
if (len >= 60) {
|
|
3318
|
+
const extra = len - 59;
|
|
3319
|
+
if (pos + extra > input.length) throw new Error("snappy: literal \u957F\u5EA6\u622A\u65AD");
|
|
3320
|
+
len = 0;
|
|
3321
|
+
for (let i = 0; i < extra; i++) len += input[pos + i] * 2 ** (8 * i);
|
|
3322
|
+
pos += extra;
|
|
3323
|
+
}
|
|
3324
|
+
len += 1;
|
|
3325
|
+
if (pos + len > input.length || opos + len > outLen) throw new Error("snappy: literal \u8D8A\u754C");
|
|
3326
|
+
input.copy(out, opos, pos, pos + len);
|
|
3327
|
+
pos += len;
|
|
3328
|
+
opos += len;
|
|
3329
|
+
} else {
|
|
3330
|
+
let len;
|
|
3331
|
+
let offset;
|
|
3332
|
+
if (type === 1) {
|
|
3333
|
+
if (pos >= input.length) throw new Error("snappy: copy1 \u622A\u65AD");
|
|
3334
|
+
len = (tag >> 2 & 7) + 4;
|
|
3335
|
+
offset = tag >> 5 << 8 | input[pos++];
|
|
3336
|
+
} else if (type === 2) {
|
|
3337
|
+
if (pos + 1 >= input.length) throw new Error("snappy: copy2 \u622A\u65AD");
|
|
3338
|
+
len = (tag >> 2) + 1;
|
|
3339
|
+
offset = input[pos] | input[pos + 1] << 8;
|
|
3340
|
+
pos += 2;
|
|
3341
|
+
} else {
|
|
3342
|
+
if (pos + 3 >= input.length) throw new Error("snappy: copy4 \u622A\u65AD");
|
|
3343
|
+
len = (tag >> 2) + 1;
|
|
3344
|
+
offset = input[pos] | input[pos + 1] << 8 | input[pos + 2] << 16 | input[pos + 3] << 24;
|
|
3345
|
+
pos += 4;
|
|
3346
|
+
}
|
|
3347
|
+
if (offset === 0 || offset > opos || opos + len > outLen) throw new Error("snappy: copy \u8D8A\u754C");
|
|
3348
|
+
for (let i = 0; i < len; i++) {
|
|
3349
|
+
out[opos] = out[opos - offset];
|
|
3350
|
+
opos++;
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
if (opos !== outLen) throw new Error(`snappy: \u89E3\u538B\u957F\u5EA6\u4E0D\u7B26 ${opos} != ${outLen}`);
|
|
3355
|
+
return out;
|
|
3356
|
+
}
|
|
3357
|
+
function readVarint(buf, pos) {
|
|
3358
|
+
let result = 0;
|
|
3359
|
+
let shift = 0;
|
|
3360
|
+
let byte;
|
|
3361
|
+
do {
|
|
3362
|
+
if (pos >= buf.length) throw new Error("varint \u8D8A\u754C");
|
|
3363
|
+
byte = buf[pos++];
|
|
3364
|
+
result += (byte & 127) * 2 ** shift;
|
|
3365
|
+
shift += 7;
|
|
3366
|
+
if (shift > 63) throw new Error("varint \u8FC7\u957F");
|
|
3367
|
+
} while (byte >= 128);
|
|
3368
|
+
return [result, pos];
|
|
3369
|
+
}
|
|
3370
|
+
function readBlock(buf, offset, size) {
|
|
3371
|
+
if (offset < 0 || size < 0 || offset + size + 1 > buf.length) return null;
|
|
3372
|
+
const raw = buf.subarray(offset, offset + size);
|
|
3373
|
+
const type = buf[offset + size];
|
|
3374
|
+
if (type === 0) return raw;
|
|
3375
|
+
if (type === 1) {
|
|
3376
|
+
try {
|
|
3377
|
+
return snappyUncompress(raw);
|
|
3378
|
+
} catch {
|
|
3379
|
+
return null;
|
|
3380
|
+
}
|
|
3381
|
+
}
|
|
3382
|
+
return null;
|
|
3383
|
+
}
|
|
3384
|
+
function blockEntries(block) {
|
|
3385
|
+
const entries = [];
|
|
3386
|
+
let pos = 0;
|
|
3387
|
+
let key = Buffer.alloc(0);
|
|
3388
|
+
while (pos < block.length) {
|
|
3389
|
+
let shared;
|
|
3390
|
+
let nonShared;
|
|
3391
|
+
let vlen;
|
|
3392
|
+
try {
|
|
3393
|
+
;
|
|
3394
|
+
[shared, pos] = readVarint(block, pos);
|
|
3395
|
+
[nonShared, pos] = readVarint(block, pos);
|
|
3396
|
+
[vlen, pos] = readVarint(block, pos);
|
|
3397
|
+
} catch {
|
|
3398
|
+
break;
|
|
3399
|
+
}
|
|
3400
|
+
if (shared === 0 && nonShared === 0 && vlen === 0) break;
|
|
3401
|
+
if (pos + nonShared + vlen > block.length) break;
|
|
3402
|
+
key = Buffer.concat([key.subarray(0, shared), block.subarray(pos, pos + nonShared)]);
|
|
3403
|
+
pos += nonShared;
|
|
3404
|
+
entries.push({ key, value: block.subarray(pos, pos + vlen) });
|
|
3405
|
+
pos += vlen;
|
|
3406
|
+
}
|
|
3407
|
+
return entries;
|
|
3408
|
+
}
|
|
3409
|
+
function sstEntries(buf) {
|
|
3410
|
+
if (buf.length < 48) return [];
|
|
3411
|
+
const footer = buf.subarray(buf.length - 48);
|
|
3412
|
+
let p = 0;
|
|
3413
|
+
let indexOff;
|
|
3414
|
+
let indexSize;
|
|
3415
|
+
try {
|
|
3416
|
+
;
|
|
3417
|
+
[, p] = readVarint(footer, p);
|
|
3418
|
+
[, p] = readVarint(footer, p);
|
|
3419
|
+
[indexOff, p] = readVarint(footer, p);
|
|
3420
|
+
[indexSize] = readVarint(footer, p);
|
|
3421
|
+
} catch {
|
|
3422
|
+
return [];
|
|
3423
|
+
}
|
|
3424
|
+
const indexBlock = readBlock(buf, indexOff, indexSize);
|
|
3425
|
+
if (!indexBlock) return [];
|
|
3426
|
+
const out = [];
|
|
3427
|
+
for (const handle of blockEntries(indexBlock)) {
|
|
3428
|
+
let r = 0;
|
|
3429
|
+
let dataOff;
|
|
3430
|
+
let dataSize;
|
|
3431
|
+
try {
|
|
3432
|
+
;
|
|
3433
|
+
[dataOff, r] = readVarint(handle.value, r);
|
|
3434
|
+
[dataSize] = readVarint(handle.value, r);
|
|
3435
|
+
} catch {
|
|
3436
|
+
continue;
|
|
3437
|
+
}
|
|
3438
|
+
const dataBlock = readBlock(buf, dataOff, dataSize);
|
|
3439
|
+
if (dataBlock) out.push(...blockEntries(dataBlock));
|
|
3440
|
+
}
|
|
3441
|
+
return out;
|
|
3442
|
+
}
|
|
3443
|
+
function logRecords(buf, stats) {
|
|
3444
|
+
const records = [];
|
|
3445
|
+
let pos = 0;
|
|
3446
|
+
let pending = null;
|
|
3447
|
+
while (pos + 7 <= buf.length) {
|
|
3448
|
+
const inBlock = pos % BLOCK_SIZE;
|
|
3449
|
+
if (inBlock > BLOCK_SIZE - 7) {
|
|
3450
|
+
pos += BLOCK_SIZE - inBlock;
|
|
3451
|
+
continue;
|
|
3452
|
+
}
|
|
3453
|
+
const masked = buf.readUInt32LE(pos);
|
|
3454
|
+
const len = buf.readUInt16LE(pos + 4);
|
|
3455
|
+
const type = buf[pos + 6];
|
|
3456
|
+
if (type === 0) {
|
|
3457
|
+
pos += 7 + len;
|
|
3458
|
+
continue;
|
|
3459
|
+
}
|
|
3460
|
+
if (pos + 7 + len > buf.length) break;
|
|
3461
|
+
const payload = buf.subarray(pos + 7, pos + 7 + len);
|
|
3462
|
+
if (unmaskCrc(masked) === crc32c(buf.subarray(pos + 6, pos + 7 + len))) {
|
|
3463
|
+
stats.goodFrames++;
|
|
3464
|
+
} else if (stats) {
|
|
3465
|
+
stats.badFrames++;
|
|
3466
|
+
}
|
|
3467
|
+
pos += 7 + len;
|
|
3468
|
+
if (type === 1) records.push(Buffer.from(payload));
|
|
3469
|
+
else if (type === 2) pending = Buffer.from(payload);
|
|
3470
|
+
else if (type === 3) pending = pending ? Buffer.concat([pending, payload]) : null;
|
|
3471
|
+
else if (type === 4) {
|
|
3472
|
+
if (pending) {
|
|
3473
|
+
records.push(Buffer.concat([pending, payload]));
|
|
3474
|
+
pending = null;
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
return records;
|
|
3479
|
+
}
|
|
3480
|
+
function batchEntries(record) {
|
|
3481
|
+
const out = [];
|
|
3482
|
+
if (record.length < 12) return out;
|
|
3483
|
+
let pos = 12;
|
|
3484
|
+
const count = record.readUInt32LE(8);
|
|
3485
|
+
for (let i = 0; i < count; i++) {
|
|
3486
|
+
if (pos >= record.length) break;
|
|
3487
|
+
const type = record[pos++];
|
|
3488
|
+
let klen;
|
|
3489
|
+
try {
|
|
3490
|
+
;
|
|
3491
|
+
[klen, pos] = readVarint(record, pos);
|
|
3492
|
+
if (pos + klen > record.length) break;
|
|
3493
|
+
const key = record.subarray(pos, pos + klen);
|
|
3494
|
+
pos += klen;
|
|
3495
|
+
if (type === 0) {
|
|
3496
|
+
out.push({ type, key, value: null });
|
|
3497
|
+
continue;
|
|
3498
|
+
}
|
|
3499
|
+
let vlen;
|
|
3500
|
+
[vlen, pos] = readVarint(record, pos);
|
|
3501
|
+
if (pos + vlen > record.length) break;
|
|
3502
|
+
const value = record.subarray(pos, pos + vlen);
|
|
3503
|
+
pos += vlen;
|
|
3504
|
+
out.push({ type, key, value });
|
|
3505
|
+
} catch {
|
|
3506
|
+
break;
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
return out;
|
|
3510
|
+
}
|
|
3511
|
+
function stripInternalKey(key) {
|
|
3512
|
+
return key.length > 8 ? key.subarray(0, key.length - 8) : key;
|
|
3513
|
+
}
|
|
3514
|
+
function readLevelDbHistory(dir) {
|
|
3515
|
+
const names = (() => {
|
|
3516
|
+
try {
|
|
3517
|
+
return readdirSync(dir).sort();
|
|
3518
|
+
} catch {
|
|
3519
|
+
return [];
|
|
3520
|
+
}
|
|
3521
|
+
})();
|
|
3522
|
+
for (const name of names.filter((n) => /\.(ldb|log)$/.test(n))) {
|
|
3523
|
+
if (!lstatSync(join10(dir, name)).isFile()) throw new Error("LevelDB entries must be regular files");
|
|
3524
|
+
}
|
|
3525
|
+
const versions = /* @__PURE__ */ new Map();
|
|
3526
|
+
const push = (key, value, seq) => {
|
|
3527
|
+
const k = key.toString("base64");
|
|
3528
|
+
const list = versions.get(k);
|
|
3529
|
+
if (list) list.push({ key, value, seq });
|
|
3530
|
+
else versions.set(k, [{ key, value, seq }]);
|
|
3531
|
+
};
|
|
3532
|
+
const stats = { goodFrames: 0, badFrames: 0 };
|
|
3533
|
+
for (const name of names.filter((n) => n.endsWith(".ldb"))) {
|
|
3534
|
+
let buf;
|
|
3535
|
+
try {
|
|
3536
|
+
buf = readFileSync(join10(dir, name));
|
|
3537
|
+
} catch {
|
|
3538
|
+
continue;
|
|
3539
|
+
}
|
|
3540
|
+
for (const e of sstEntries(buf)) {
|
|
3541
|
+
const seq = e.key.length > 8 ? Number(e.key.readBigUInt64LE(e.key.length - 8) >> 8n) : 0;
|
|
3542
|
+
push(stripInternalKey(e.key), e.value, seq);
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
for (const name of names.filter((n) => n.endsWith(".log"))) {
|
|
3546
|
+
let buf;
|
|
3547
|
+
try {
|
|
3548
|
+
buf = readFileSync(join10(dir, name));
|
|
3549
|
+
} catch {
|
|
3550
|
+
continue;
|
|
3551
|
+
}
|
|
3552
|
+
for (const rec of logRecords(buf, stats)) {
|
|
3553
|
+
if (rec.length < 12) continue;
|
|
3554
|
+
const base = Number(rec.readBigUInt64LE(0) >> 8n);
|
|
3555
|
+
for (const e of batchEntries(rec)) {
|
|
3556
|
+
push(e.key, e.type === 0 ? null : e.value, base);
|
|
3557
|
+
}
|
|
3558
|
+
}
|
|
3559
|
+
}
|
|
3560
|
+
for (const list of versions.values()) {
|
|
3561
|
+
if (list.length > 1) list.sort((a, b) => a.seq - b.seq);
|
|
3562
|
+
}
|
|
3563
|
+
return versions;
|
|
3564
|
+
}
|
|
3565
|
+
var OBJECT_STORE_DATA_INDEX_ID = 1;
|
|
3566
|
+
function decodeKeyPrefix(key) {
|
|
3567
|
+
if (key.length < 4) return null;
|
|
3568
|
+
const first = key[0];
|
|
3569
|
+
const dbBytes = (first >> 5 & 7) + 1;
|
|
3570
|
+
const osBytes = (first >> 2 & 7) + 1;
|
|
3571
|
+
const indexBytes = (first & 3) + 1;
|
|
3572
|
+
if (1 + dbBytes + osBytes + indexBytes > key.length) return null;
|
|
3573
|
+
let pos = 1;
|
|
3574
|
+
const readInt = (n) => {
|
|
3575
|
+
let v = 0n;
|
|
3576
|
+
for (let i = n - 1; i >= 0; i--) v = v << 8n | BigInt(key[pos + i]);
|
|
3577
|
+
pos += n;
|
|
3578
|
+
return Number(v);
|
|
3579
|
+
};
|
|
3580
|
+
const databaseId = readInt(dbBytes);
|
|
3581
|
+
const objectStoreId = readInt(osBytes);
|
|
3582
|
+
const indexId = readInt(indexBytes);
|
|
3583
|
+
return { databaseId, objectStoreId, indexId, end: pos };
|
|
3584
|
+
}
|
|
3585
|
+
function decodeIdbKey(buf, pos = 0) {
|
|
3586
|
+
const type = buf[pos++];
|
|
3587
|
+
switch (type) {
|
|
3588
|
+
case 0:
|
|
3589
|
+
return { value: null, pos };
|
|
3590
|
+
case 1: {
|
|
3591
|
+
const [len, p] = readVarint(buf, pos);
|
|
3592
|
+
if (p + len * 2 > buf.length) throw new Error("IndexedDB \u5B57\u7B26\u4E32\u952E\u8D8A\u754C");
|
|
3593
|
+
let text = "";
|
|
3594
|
+
for (let i = 0; i < len; i++) text += String.fromCharCode(buf.readUInt16BE(p + i * 2));
|
|
3595
|
+
return { value: text, pos: p + len * 2 };
|
|
3596
|
+
}
|
|
3597
|
+
case 2:
|
|
3598
|
+
case 3:
|
|
3599
|
+
return { value: buf.readDoubleLE(pos), pos: pos + 8 };
|
|
3600
|
+
case 4: {
|
|
3601
|
+
const [len, p] = readVarint(buf, pos);
|
|
3602
|
+
const items = [];
|
|
3603
|
+
let at = p;
|
|
3604
|
+
for (let i = 0; i < len; i++) {
|
|
3605
|
+
const r = decodeIdbKey(buf, at);
|
|
3606
|
+
items.push(r.value);
|
|
3607
|
+
at = r.pos;
|
|
3608
|
+
}
|
|
3609
|
+
return { value: items, pos: at };
|
|
3610
|
+
}
|
|
3611
|
+
case 5:
|
|
3612
|
+
return { value: null, pos };
|
|
3613
|
+
case 6: {
|
|
3614
|
+
const [len, p] = readVarint(buf, pos);
|
|
3615
|
+
return { value: buf.subarray(p, p + len), pos: p + len };
|
|
3616
|
+
}
|
|
3617
|
+
default:
|
|
3618
|
+
throw new Error("\u672A\u77E5 IndexedDB \u952E\u7C7B\u578B " + type);
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
function unwrapIdbValue(value) {
|
|
3622
|
+
for (let off = 0; off < Math.min(8, value.length - 2); off++) {
|
|
3623
|
+
if (value[off] !== 255 || value[off + 1] !== 17) continue;
|
|
3624
|
+
const kind = value[off + 2];
|
|
3625
|
+
if (kind === 2) {
|
|
3626
|
+
try {
|
|
3627
|
+
return snappyUncompress(value.subarray(off + 3));
|
|
3628
|
+
} catch {
|
|
3629
|
+
return null;
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
if (kind === 1) return null;
|
|
3633
|
+
}
|
|
3634
|
+
return value;
|
|
3635
|
+
}
|
|
3636
|
+
function ssvPayloadOffset(buf) {
|
|
3637
|
+
for (let i = 0; i + 2 < buf.length && i < 8; i++) {
|
|
3638
|
+
if (buf[i] !== 255) continue;
|
|
3639
|
+
let pos = i + 1;
|
|
3640
|
+
try {
|
|
3641
|
+
let [, p] = readVarint(buf, pos);
|
|
3642
|
+
if (buf[p] === 254) {
|
|
3643
|
+
const end = p + 1 + 8 + 4;
|
|
3644
|
+
return end <= buf.length ? end : -1;
|
|
3645
|
+
}
|
|
3646
|
+
return p;
|
|
3647
|
+
} catch {
|
|
3648
|
+
return -1;
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
return -1;
|
|
3652
|
+
}
|
|
3653
|
+
var V8_VERSION = 255;
|
|
3654
|
+
var V8_PADDING = 0;
|
|
3655
|
+
var V8_VERIFY_COUNT = 63;
|
|
3656
|
+
var V8_THE_HOLE = 45;
|
|
3657
|
+
var V8_UNDEFINED = 95;
|
|
3658
|
+
var V8_NULL = 48;
|
|
3659
|
+
var V8_TRUE = 84;
|
|
3660
|
+
var V8_FALSE = 70;
|
|
3661
|
+
var V8_INT32 = 73;
|
|
3662
|
+
var V8_UINT32 = 85;
|
|
3663
|
+
var V8_DOUBLE = 78;
|
|
3664
|
+
var V8_BIGINT = 90;
|
|
3665
|
+
var V8_UTF8_STRING = 83;
|
|
3666
|
+
var V8_ONE_BYTE_STRING = 34;
|
|
3667
|
+
var V8_TWO_BYTE_STRING = 99;
|
|
3668
|
+
var V8_OBJECT_REFERENCE = 94;
|
|
3669
|
+
var V8_BEGIN_OBJECT = 111;
|
|
3670
|
+
var V8_END_OBJECT = 123;
|
|
3671
|
+
var V8_BEGIN_SPARSE_ARRAY = 97;
|
|
3672
|
+
var V8_END_SPARSE_ARRAY = 64;
|
|
3673
|
+
var V8_BEGIN_DENSE_ARRAY = 65;
|
|
3674
|
+
var V8_END_DENSE_ARRAY = 36;
|
|
3675
|
+
var V8_DATE = 68;
|
|
3676
|
+
var V8_TRUE_OBJECT = 121;
|
|
3677
|
+
var V8_FALSE_OBJECT = 120;
|
|
3678
|
+
var V8_NUMBER_OBJECT = 110;
|
|
3679
|
+
var V8_STRING_OBJECT = 115;
|
|
3680
|
+
var V8_BIGINT_OBJECT = 122;
|
|
3681
|
+
var V8_REGEXP = 82;
|
|
3682
|
+
var V8_BEGIN_MAP = 59;
|
|
3683
|
+
var V8_END_MAP = 58;
|
|
3684
|
+
var V8_BEGIN_SET = 39;
|
|
3685
|
+
var V8_END_SET = 44;
|
|
3686
|
+
var V8_ARRAY_BUFFER = 66;
|
|
3687
|
+
var V8_IMMUTABLE_ARRAY_BUFFER = 67;
|
|
3688
|
+
var V8_RESIZABLE_ARRAY_BUFFER = 126;
|
|
3689
|
+
var V8_ERROR = 114;
|
|
3690
|
+
var V8_HOST_OBJECT = 92;
|
|
3691
|
+
var V8_SHARED_OBJECT = 112;
|
|
3692
|
+
function deserializeV8(buf, start = 0) {
|
|
3693
|
+
let pos = start;
|
|
3694
|
+
let nextId = 0;
|
|
3695
|
+
const table = [];
|
|
3696
|
+
const varint = () => {
|
|
3697
|
+
const [v, p] = readVarint(buf, pos);
|
|
3698
|
+
pos = p;
|
|
3699
|
+
return v;
|
|
3700
|
+
};
|
|
3701
|
+
const dbl = () => {
|
|
3702
|
+
if (pos + 8 > buf.length) throw new Error("V8: double \u8D8A\u754C");
|
|
3703
|
+
const v = buf.readDoubleLE(pos);
|
|
3704
|
+
pos += 8;
|
|
3705
|
+
return v;
|
|
3706
|
+
};
|
|
3707
|
+
const stringOf = (encoding, length) => {
|
|
3708
|
+
const bytes = encoding === "utf16" ? length * 2 : length;
|
|
3709
|
+
if (pos + bytes > buf.length) throw new Error("V8: \u5B57\u7B26\u4E32\u8D8A\u754C");
|
|
3710
|
+
const s = encoding === "utf16" ? buf.toString("utf16le", pos, pos + bytes) : buf.toString(encoding, pos, pos + bytes);
|
|
3711
|
+
pos += bytes;
|
|
3712
|
+
return s;
|
|
3713
|
+
};
|
|
3714
|
+
const read = () => {
|
|
3715
|
+
if (pos >= buf.length) throw new Error("V8: \u6D41\u622A\u65AD");
|
|
3716
|
+
const tag = buf[pos++];
|
|
3717
|
+
switch (tag) {
|
|
3718
|
+
case V8_VERSION:
|
|
3719
|
+
varint();
|
|
3720
|
+
return read();
|
|
3721
|
+
case V8_PADDING:
|
|
3722
|
+
return read();
|
|
3723
|
+
case V8_VERIFY_COUNT:
|
|
3724
|
+
varint();
|
|
3725
|
+
return read();
|
|
3726
|
+
case V8_UNDEFINED:
|
|
3727
|
+
case V8_THE_HOLE:
|
|
3728
|
+
return void 0;
|
|
3729
|
+
case V8_NULL:
|
|
3730
|
+
return null;
|
|
3731
|
+
case V8_TRUE:
|
|
3732
|
+
return true;
|
|
3733
|
+
case V8_FALSE:
|
|
3734
|
+
return false;
|
|
3735
|
+
case V8_INT32: {
|
|
3736
|
+
const v = varint();
|
|
3737
|
+
return v >>> 1 ^ -(v & 1);
|
|
3738
|
+
}
|
|
3739
|
+
case V8_UINT32:
|
|
3740
|
+
return varint();
|
|
3741
|
+
case V8_DOUBLE:
|
|
3742
|
+
return dbl();
|
|
3743
|
+
case V8_BIGINT: {
|
|
3744
|
+
const bitfield = varint();
|
|
3745
|
+
pos += Math.ceil((bitfield >>> 2 || 1) / 8) * 8;
|
|
3746
|
+
return null;
|
|
3747
|
+
}
|
|
3748
|
+
case V8_UTF8_STRING:
|
|
3749
|
+
return stringOf("utf8", varint());
|
|
3750
|
+
case V8_ONE_BYTE_STRING:
|
|
3751
|
+
return stringOf("latin1", varint());
|
|
3752
|
+
case V8_TWO_BYTE_STRING: {
|
|
3753
|
+
if (buf[pos] === V8_PADDING) pos++;
|
|
3754
|
+
const bytes = varint();
|
|
3755
|
+
return stringOf("utf16", bytes / 2);
|
|
3756
|
+
}
|
|
3757
|
+
case V8_OBJECT_REFERENCE:
|
|
3758
|
+
return table[varint()];
|
|
3759
|
+
case V8_BEGIN_OBJECT: {
|
|
3760
|
+
const obj = {};
|
|
3761
|
+
table[nextId++] = obj;
|
|
3762
|
+
for (; ; ) {
|
|
3763
|
+
if (pos >= buf.length) throw new Error("V8: \u5BF9\u8C61\u672A\u95ED\u5408");
|
|
3764
|
+
if (buf[pos] === V8_END_OBJECT) {
|
|
3765
|
+
pos++;
|
|
3766
|
+
varint();
|
|
3767
|
+
return obj;
|
|
3768
|
+
}
|
|
3769
|
+
const key = read();
|
|
3770
|
+
obj[String(key)] = read();
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
case V8_BEGIN_DENSE_ARRAY: {
|
|
3774
|
+
const len = varint();
|
|
3775
|
+
const arr = new Array(len);
|
|
3776
|
+
table[nextId++] = arr;
|
|
3777
|
+
for (let i = 0; i < len; i++) arr[i] = read();
|
|
3778
|
+
if (buf[pos] === V8_END_DENSE_ARRAY) {
|
|
3779
|
+
pos++;
|
|
3780
|
+
varint();
|
|
3781
|
+
varint();
|
|
3782
|
+
}
|
|
3783
|
+
return arr;
|
|
3784
|
+
}
|
|
3785
|
+
case V8_BEGIN_SPARSE_ARRAY: {
|
|
3786
|
+
const len = varint();
|
|
3787
|
+
const arr = new Array(len);
|
|
3788
|
+
table[nextId++] = arr;
|
|
3789
|
+
for (; ; ) {
|
|
3790
|
+
if (pos >= buf.length) throw new Error("V8: \u7A00\u758F\u6570\u7EC4\u672A\u95ED\u5408");
|
|
3791
|
+
if (buf[pos] === V8_END_SPARSE_ARRAY) {
|
|
3792
|
+
pos++;
|
|
3793
|
+
varint();
|
|
3794
|
+
varint();
|
|
3795
|
+
return arr;
|
|
3796
|
+
}
|
|
3797
|
+
const key = read();
|
|
3798
|
+
arr[Number(key)] = read();
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
case V8_DATE:
|
|
3802
|
+
table[nextId++] = new Date(dbl());
|
|
3803
|
+
return table[nextId - 1];
|
|
3804
|
+
case V8_TRUE_OBJECT:
|
|
3805
|
+
table[nextId] = true;
|
|
3806
|
+
return table[nextId++];
|
|
3807
|
+
case V8_FALSE_OBJECT:
|
|
3808
|
+
table[nextId] = false;
|
|
3809
|
+
return table[nextId++];
|
|
3810
|
+
case V8_NUMBER_OBJECT:
|
|
3811
|
+
table[nextId++] = dbl();
|
|
3812
|
+
return table[nextId - 1];
|
|
3813
|
+
case V8_BIGINT_OBJECT: {
|
|
3814
|
+
const bitfield = varint();
|
|
3815
|
+
pos += Math.ceil((bitfield >>> 2 || 1) / 8) * 8;
|
|
3816
|
+
return null;
|
|
3817
|
+
}
|
|
3818
|
+
case V8_STRING_OBJECT:
|
|
3819
|
+
return read();
|
|
3820
|
+
case V8_REGEXP: {
|
|
3821
|
+
const pattern = read();
|
|
3822
|
+
varint();
|
|
3823
|
+
return pattern instanceof RegExp ? pattern : new RegExp(String(pattern));
|
|
3824
|
+
}
|
|
3825
|
+
case V8_BEGIN_MAP: {
|
|
3826
|
+
const map = /* @__PURE__ */ new Map();
|
|
3827
|
+
table[nextId++] = map;
|
|
3828
|
+
for (; ; ) {
|
|
3829
|
+
if (pos >= buf.length) throw new Error("V8: Map \u672A\u95ED\u5408");
|
|
3830
|
+
if (buf[pos] === V8_END_MAP) {
|
|
3831
|
+
pos++;
|
|
3832
|
+
varint();
|
|
3833
|
+
return map;
|
|
3834
|
+
}
|
|
3835
|
+
const key = read();
|
|
3836
|
+
map.set(key, read());
|
|
3837
|
+
}
|
|
3838
|
+
}
|
|
3839
|
+
case V8_BEGIN_SET: {
|
|
3840
|
+
const set = /* @__PURE__ */ new Set();
|
|
3841
|
+
table[nextId++] = set;
|
|
3842
|
+
for (; ; ) {
|
|
3843
|
+
if (pos >= buf.length) throw new Error("V8: Set \u672A\u95ED\u5408");
|
|
3844
|
+
if (buf[pos] === V8_END_SET) {
|
|
3845
|
+
pos++;
|
|
3846
|
+
varint();
|
|
3847
|
+
return set;
|
|
3848
|
+
}
|
|
3849
|
+
set.add(read());
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
case V8_ARRAY_BUFFER:
|
|
3853
|
+
case V8_IMMUTABLE_ARRAY_BUFFER: {
|
|
3854
|
+
const len = varint();
|
|
3855
|
+
if (pos + len > buf.length) throw new Error("V8: ArrayBuffer \u8D8A\u754C");
|
|
3856
|
+
const bytes = buf.subarray(pos, pos + len);
|
|
3857
|
+
pos += len;
|
|
3858
|
+
table[nextId++] = bytes;
|
|
3859
|
+
return bytes;
|
|
3860
|
+
}
|
|
3861
|
+
case V8_RESIZABLE_ARRAY_BUFFER: {
|
|
3862
|
+
const len = varint();
|
|
3863
|
+
varint();
|
|
3864
|
+
if (pos + len > buf.length) throw new Error("V8: \u53EF\u53D8 ArrayBuffer \u8D8A\u754C");
|
|
3865
|
+
const bytes = buf.subarray(pos, pos + len);
|
|
3866
|
+
pos += len;
|
|
3867
|
+
table[nextId++] = bytes;
|
|
3868
|
+
return bytes;
|
|
3869
|
+
}
|
|
3870
|
+
case V8_ERROR: {
|
|
3871
|
+
const err2 = { name: "Error", message: "", stack: "" };
|
|
3872
|
+
table[nextId++] = err2;
|
|
3873
|
+
let sub = buf[pos++];
|
|
3874
|
+
for (; ; ) {
|
|
3875
|
+
if (sub === 46) break;
|
|
3876
|
+
if (sub === 109) err2.message = String(read());
|
|
3877
|
+
else if (sub === 115) err2.stack = String(read());
|
|
3878
|
+
else if (sub === 99) err2.cause = read();
|
|
3879
|
+
else if (sub >= 69 && sub <= 85) err2.name = "Error";
|
|
3880
|
+
sub = buf[pos++];
|
|
3881
|
+
}
|
|
3882
|
+
return err2;
|
|
3883
|
+
}
|
|
3884
|
+
case V8_HOST_OBJECT:
|
|
3885
|
+
return "[host object]";
|
|
3886
|
+
case V8_SHARED_OBJECT:
|
|
3887
|
+
varint();
|
|
3888
|
+
return "[shared object]";
|
|
3889
|
+
default:
|
|
3890
|
+
throw new Error(`V8: \u672A\u77E5 tag 0x${tag.toString(16)} @${pos - 1}`);
|
|
3891
|
+
}
|
|
3892
|
+
};
|
|
3893
|
+
const value = read();
|
|
3894
|
+
return { value, consumed: pos - start, total: buf.length - start };
|
|
3895
|
+
}
|
|
3896
|
+
function decodeIdbValue(value) {
|
|
3897
|
+
const body = unwrapIdbValue(value);
|
|
3898
|
+
if (!body) return void 0;
|
|
3899
|
+
const start = ssvPayloadOffset(body);
|
|
3900
|
+
const candidates = start >= 0 ? [start] : [];
|
|
3901
|
+
for (let i = 0; i < 8; i++) if (!candidates.includes(i)) candidates.push(i);
|
|
3902
|
+
for (const off of candidates) {
|
|
3903
|
+
try {
|
|
3904
|
+
return deserializeV8(body, off).value;
|
|
3905
|
+
} catch {
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
return void 0;
|
|
3909
|
+
}
|
|
3910
|
+
function readIndexedDb(dir) {
|
|
3911
|
+
const history = readLevelDbHistory(dir);
|
|
3912
|
+
const data = [];
|
|
3913
|
+
let undecodable = 0;
|
|
3914
|
+
let rawCount = 0;
|
|
3915
|
+
for (const versions of history.values()) {
|
|
3916
|
+
const first = versions[0];
|
|
3917
|
+
rawCount += versions.length;
|
|
3918
|
+
const prefix = decodeKeyPrefix(first.key);
|
|
3919
|
+
if (!prefix || prefix.indexId !== OBJECT_STORE_DATA_INDEX_ID) continue;
|
|
3920
|
+
let userKey;
|
|
3921
|
+
try {
|
|
3922
|
+
;
|
|
3923
|
+
({ value: userKey } = decodeIdbKey(first.key, prefix.end));
|
|
3924
|
+
} catch {
|
|
3925
|
+
undecodable++;
|
|
3926
|
+
continue;
|
|
3927
|
+
}
|
|
3928
|
+
const decoded = [];
|
|
3929
|
+
for (const v of versions) {
|
|
3930
|
+
if (v.value === null) continue;
|
|
3931
|
+
const value = decodeIdbValue(v.value);
|
|
3932
|
+
if (value !== void 0) decoded.push(value);
|
|
3933
|
+
}
|
|
3934
|
+
if (decoded.length === 0) {
|
|
3935
|
+
undecodable++;
|
|
3936
|
+
continue;
|
|
3937
|
+
}
|
|
3938
|
+
data.push({
|
|
3939
|
+
databaseId: prefix.databaseId,
|
|
3940
|
+
objectStoreId: prefix.objectStoreId,
|
|
3941
|
+
key: userKey,
|
|
3942
|
+
value: decoded[decoded.length - 1],
|
|
3943
|
+
versions: decoded,
|
|
3944
|
+
versionCount: versions.length
|
|
3945
|
+
});
|
|
3946
|
+
}
|
|
3947
|
+
return { records: data, undecodable, rawCount };
|
|
3948
|
+
}
|
|
3949
|
+
|
|
3950
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/doubao.mjs
|
|
3951
|
+
var DOUBAO_IDB_SUFFIX = ".indexeddb.leveldb";
|
|
3952
|
+
var DOUBAO_CHAT_ORIGIN = "chrome_doubao-chat";
|
|
3953
|
+
function doubaoUserDataDirs(home, env = process.env, platform = process.platform) {
|
|
3954
|
+
if (platform === "win32") {
|
|
3955
|
+
const local = env.LOCALAPPDATA || (home ? join11(home, "AppData", "Local") : null);
|
|
3956
|
+
if (!local) return [];
|
|
3957
|
+
return [join11(local, "Doubao", "User Data")];
|
|
3958
|
+
}
|
|
3959
|
+
if (platform === "darwin") {
|
|
3960
|
+
return home ? [join11(home, "Library", "Application Support", "Doubao")] : [];
|
|
3961
|
+
}
|
|
3962
|
+
return home ? [join11(home, ".config", "Doubao")] : [];
|
|
3963
|
+
}
|
|
3964
|
+
function doubaoIndexedDbDirs(entries, originPrefix = DOUBAO_CHAT_ORIGIN) {
|
|
3965
|
+
const dirs = [];
|
|
3966
|
+
for (const entry of Array.isArray(entries) ? entries : []) {
|
|
3967
|
+
const path = entry && (entry.path || entry.name);
|
|
3968
|
+
if (!path) continue;
|
|
3969
|
+
const base = String(entry.name ?? String(path).split(/[\\/]/).pop());
|
|
3970
|
+
if (!base.endsWith(DOUBAO_IDB_SUFFIX)) continue;
|
|
3971
|
+
if (originPrefix && !base.startsWith(originPrefix)) continue;
|
|
3972
|
+
dirs.push({ path, name: base });
|
|
3973
|
+
}
|
|
3974
|
+
dirs.sort((a, b) => Number(!a.name.startsWith(DOUBAO_CHAT_ORIGIN)) - Number(!b.name.startsWith(DOUBAO_CHAT_ORIGIN)));
|
|
3975
|
+
return dirs.map((d) => d.path);
|
|
3976
|
+
}
|
|
3977
|
+
function readDoubaoDb(dir) {
|
|
3978
|
+
let db;
|
|
3979
|
+
try {
|
|
3980
|
+
db = readIndexedDb(dir);
|
|
3981
|
+
} catch {
|
|
3982
|
+
return null;
|
|
3983
|
+
}
|
|
3984
|
+
if (!db || db.rawCount === 0) return null;
|
|
3985
|
+
const { sessions, stats } = extractDoubaoSessions(db);
|
|
3986
|
+
return { sessions, stats, undecodable: db.undecodable, rawCount: db.rawCount };
|
|
3987
|
+
}
|
|
3988
|
+
function readDoubaoSessionSummaries(dir) {
|
|
3989
|
+
const read = readDoubaoDb(dir);
|
|
3990
|
+
if (!read) return null;
|
|
3991
|
+
return read.sessions.map((session) => ({
|
|
3992
|
+
id: session.id,
|
|
3993
|
+
title: normalizeTitle(session.title),
|
|
3994
|
+
directory: null,
|
|
3995
|
+
createdAt: session.createdAt ?? void 0,
|
|
3996
|
+
lastActiveAt: session.updatedAt ?? session.createdAt ?? void 0
|
|
3997
|
+
}));
|
|
3998
|
+
}
|
|
3999
|
+
|
|
4000
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/indexeddb.mjs
|
|
4001
|
+
async function indexedDbFingerprint(host2, dir) {
|
|
4002
|
+
const entries = await host2.readDir(dir);
|
|
4003
|
+
if (!entries) return "";
|
|
4004
|
+
const parts = [];
|
|
4005
|
+
for (const entry of entries) {
|
|
4006
|
+
if (entry.type !== "file") continue;
|
|
4007
|
+
const name = entry.name;
|
|
4008
|
+
if (!name.endsWith(".ldb") && !name.endsWith(".log")) continue;
|
|
4009
|
+
const path = entry.path || join12(dir, name);
|
|
4010
|
+
const st = await host2.stat(path);
|
|
4011
|
+
parts.push(name + ":" + (st ? String(st.size ?? "") + ":" + String(st.mtimeMs ?? "") : "?"));
|
|
4012
|
+
}
|
|
4013
|
+
return parts.sort().join("|");
|
|
4014
|
+
}
|
|
4015
|
+
async function doubaoDbDirs(host2, target) {
|
|
4016
|
+
const st = await host2.stat(target);
|
|
4017
|
+
if (!st) return [];
|
|
4018
|
+
if (st.type === "file") return [];
|
|
4019
|
+
const base = String(target).split(/[\\/]/).filter(Boolean).pop() || "";
|
|
4020
|
+
if (base.endsWith(DOUBAO_IDB_SUFFIX)) return [target];
|
|
4021
|
+
if (base === "IndexedDB") return doubaoIndexedDbDirs(await listChildren(host2, target));
|
|
4022
|
+
const out = [];
|
|
4023
|
+
const walk = async (dir, depth) => {
|
|
4024
|
+
if (depth > 2) return;
|
|
4025
|
+
const entries = await listChildren(host2, dir);
|
|
4026
|
+
for (const entry of entries) {
|
|
4027
|
+
if (entry.type !== "directory") continue;
|
|
4028
|
+
const path = entry.path || join12(dir, entry.name);
|
|
4029
|
+
if (entry.name === "IndexedDB") {
|
|
4030
|
+
out.push(...doubaoIndexedDbDirs(await listChildren(host2, path)));
|
|
4031
|
+
continue;
|
|
4032
|
+
}
|
|
4033
|
+
await walk(path, depth + 1);
|
|
4034
|
+
}
|
|
4035
|
+
};
|
|
4036
|
+
await walk(target, 0);
|
|
4037
|
+
return out;
|
|
4038
|
+
}
|
|
4039
|
+
async function listChildren(host2, dir) {
|
|
4040
|
+
const entries = await host2.readDir(dir);
|
|
4041
|
+
if (!entries) return [];
|
|
4042
|
+
return entries.map((entry) => ({
|
|
4043
|
+
name: entry.name,
|
|
4044
|
+
type: entry.type,
|
|
4045
|
+
path: entry.path || join12(dir, entry.name)
|
|
4046
|
+
}));
|
|
4047
|
+
}
|
|
4048
|
+
async function scanDoubao(host2, target, { bm, emit }) {
|
|
4049
|
+
const dirs = await doubaoDbDirs(host2, target);
|
|
4050
|
+
const out = [];
|
|
4051
|
+
for (const dir of dirs) {
|
|
4052
|
+
const dirStat = await host2.stat(dir);
|
|
4053
|
+
if (!dirStat) continue;
|
|
4054
|
+
const fp = { mtimeMs: await indexedDbFingerprint(host2, dir), sizeBytes: 0 };
|
|
4055
|
+
const entries = await probeSource(bm, "doubao", dir, fp, async () => {
|
|
4056
|
+
const sessions = await host2.readSessions("doubao", dir);
|
|
4057
|
+
if (!sessions) return [];
|
|
4058
|
+
return sessions.map((s) => makeEntry({
|
|
4059
|
+
format: "doubao",
|
|
4060
|
+
sessionId: s.id,
|
|
4061
|
+
title: normalizeTitle(s.title),
|
|
4062
|
+
project: null,
|
|
4063
|
+
createdAt: s.createdAt,
|
|
4064
|
+
lastActiveAt: s.lastActiveAt,
|
|
4065
|
+
sourcePath: dir,
|
|
4066
|
+
cwd: null
|
|
4067
|
+
}));
|
|
4068
|
+
});
|
|
4069
|
+
out.push(...entries);
|
|
4070
|
+
await emitEach(emit, entries);
|
|
4071
|
+
}
|
|
4072
|
+
return out;
|
|
4073
|
+
}
|
|
4074
|
+
var doubaoSource = {
|
|
4075
|
+
format: "doubao",
|
|
4076
|
+
// 摘要读取器在 host 侧(lib/discovery-host.mjs 的 DB_SUMMARY_FORMATS)
|
|
4077
|
+
sessionsFromHost: true,
|
|
4078
|
+
// 默认根:Windows %LOCALAPPDATA%\Doubao\User Data;macOS/Linux 按 Electron 默认 appData
|
|
4079
|
+
roots: (home, env) => doubaoUserDataDirs(home, env),
|
|
4080
|
+
scan: scanDoubao
|
|
4081
|
+
// 单文件形态不存在(库是目录),所以不给 matchFile / fileFallback:显式传某库目录或
|
|
4082
|
+
// IndexedDB 目录即可发现。
|
|
4083
|
+
};
|
|
4084
|
+
|
|
4085
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/documents.mjs
|
|
4086
|
+
import { join as join13 } from "node:path";
|
|
2977
4087
|
async function scanChatgpt(host2, target, { bm, emit }) {
|
|
2978
4088
|
const st = await host2.stat(target);
|
|
2979
4089
|
if (!st) return [];
|
|
2980
4090
|
let file = target;
|
|
2981
4091
|
if (st.type === "directory") {
|
|
2982
|
-
const candidate =
|
|
4092
|
+
const candidate = join13(target, "conversations.json");
|
|
2983
4093
|
const cst = await host2.stat(candidate);
|
|
2984
4094
|
if (!cst || cst.type !== "file") return [];
|
|
2985
4095
|
file = candidate;
|
|
@@ -3085,7 +4195,7 @@ var continueSource = {
|
|
|
3085
4195
|
format: "continue",
|
|
3086
4196
|
// 全局单一会话目录(VS Code / JetBrains / CLI 三端共用);与 Continue core 同序:
|
|
3087
4197
|
// $CONTINUE_GLOBAL_DIR 优先、否则 ~/.continue
|
|
3088
|
-
roots: (home, env) => env.CONTINUE_GLOBAL_DIR ?
|
|
4198
|
+
roots: (home, env) => env.CONTINUE_GLOBAL_DIR ? join13(env.CONTINUE_GLOBAL_DIR, "sessions") : join13(home, ".continue", "sessions"),
|
|
3089
4199
|
scan: scanContinue,
|
|
3090
4200
|
// 会话文件是单个 JSON 对象且路径特征唯一 → 独占,不落到 gemini/chatgpt 探测
|
|
3091
4201
|
matchFile: (lower) => lower.endsWith(".json") && /(^|[\\/])\.continue[\\/]sessions[\\/]/.test(lower) ? "only" : false
|
|
@@ -3098,13 +4208,13 @@ var chatgptSource = {
|
|
|
3098
4208
|
fileFallback: ["json"]
|
|
3099
4209
|
};
|
|
3100
4210
|
|
|
3101
|
-
// .codex-tmp/
|
|
3102
|
-
import { join as
|
|
4211
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/dsh.mjs
|
|
4212
|
+
import { join as join14 } from "node:path";
|
|
3103
4213
|
|
|
3104
|
-
// .codex-tmp/
|
|
4214
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/dsh.mjs
|
|
3105
4215
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
3106
4216
|
|
|
3107
|
-
// .codex-tmp/
|
|
4217
|
+
// .codex-tmp/chat-import-0263/package/node_modules/fzstd/esm/index.mjs
|
|
3108
4218
|
var ab = ArrayBuffer;
|
|
3109
4219
|
var u8 = Uint8Array;
|
|
3110
4220
|
var u16 = Uint16Array;
|
|
@@ -3725,7 +4835,7 @@ function decompress(dat, buf) {
|
|
|
3725
4835
|
return cct(bufs, ol);
|
|
3726
4836
|
}
|
|
3727
4837
|
|
|
3728
|
-
// .codex-tmp/
|
|
4838
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/dsh.mjs
|
|
3729
4839
|
var DSH_SESSION_LOG = /^session(?:\.v([1-9][0-9]*))?\.jsonl(?:\.zstd)?$/i;
|
|
3730
4840
|
function dshSessionLogVersion(name) {
|
|
3731
4841
|
const m = DSH_SESSION_LOG.exec(String(name || ""));
|
|
@@ -3738,7 +4848,7 @@ async function decodeZstdText(buf) {
|
|
|
3738
4848
|
return Buffer2.from(decompress(buf)).toString("utf8");
|
|
3739
4849
|
}
|
|
3740
4850
|
|
|
3741
|
-
// .codex-tmp/
|
|
4851
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/dsh.mjs
|
|
3742
4852
|
function decodeDshProjectKey(encoded) {
|
|
3743
4853
|
return String(encoded).replace(/~([0-9A-Fa-f]{4})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
|
|
3744
4854
|
}
|
|
@@ -3818,7 +4928,7 @@ function dshLayoutProject(sourcePath) {
|
|
|
3818
4928
|
function dshFormatOf(fileName) {
|
|
3819
4929
|
return (dshSessionLogVersion(fileName) ?? 0) >= 4 ? "dsh4" : "dsh";
|
|
3820
4930
|
}
|
|
3821
|
-
var dshRoots = (home, env) =>
|
|
4931
|
+
var dshRoots = (home, env) => join14(env.DSH_HOME || join14(home, ".dsh"), "sessions");
|
|
3822
4932
|
var dshMatchFile = (format) => (lower, base) => /(^|[\\/])sessions[\\/]/.test(lower) && isDshSessionFile(base) && dshFormatOf(base) === format ? "only" : false;
|
|
3823
4933
|
var dshSource = {
|
|
3824
4934
|
format: "dsh",
|
|
@@ -3835,7 +4945,120 @@ var dsh4Source = {
|
|
|
3835
4945
|
matchFile: dshMatchFile("dsh4")
|
|
3836
4946
|
};
|
|
3837
4947
|
|
|
3838
|
-
// .codex-tmp/
|
|
4948
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/copilot-vscode.mjs
|
|
4949
|
+
function copilotVscodeWorkspacePath(path) {
|
|
4950
|
+
const match = String(path).match(/^(.*)[\\/]chatSessions[\\/][^\\/]+\.json$/i);
|
|
4951
|
+
if (!match) return null;
|
|
4952
|
+
const sep = match[1].includes("\\") ? "\\" : "/";
|
|
4953
|
+
return match[1] + sep + "workspace.json";
|
|
4954
|
+
}
|
|
4955
|
+
function readCopilotVscodeWorkspace(raw) {
|
|
4956
|
+
try {
|
|
4957
|
+
return copilotVscodeCwd(JSON.parse(raw)?.folder);
|
|
4958
|
+
} catch {
|
|
4959
|
+
return null;
|
|
4960
|
+
}
|
|
4961
|
+
}
|
|
4962
|
+
|
|
4963
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/copilot-vscode.mjs
|
|
4964
|
+
function copilotVscodeRoots(home, env = {}, platform = process.platform) {
|
|
4965
|
+
if (isAbsoluteLike(env.COPILOT_VSCODE_STORAGE_DIR || "")) return [env.COPILOT_VSCODE_STORAGE_DIR];
|
|
4966
|
+
const path = (...parts) => joinForPlatform(platform, ...parts);
|
|
4967
|
+
let base;
|
|
4968
|
+
if (platform === "win32") base = env.APPDATA || path(home, "AppData", "Roaming");
|
|
4969
|
+
else if (platform === "darwin") base = path(home, "Library", "Application Support");
|
|
4970
|
+
else base = isAbsoluteLike(env.XDG_CONFIG_HOME || "") ? env.XDG_CONFIG_HOME : path(home, ".config");
|
|
4971
|
+
return ["Code", "Code - Insiders", "VSCodium"].map((name) => path(base, name, "User", "workspaceStorage"));
|
|
4972
|
+
}
|
|
4973
|
+
async function scanCopilotVscode(host2, target, { bm, emit }) {
|
|
4974
|
+
const st = await host2.stat(target);
|
|
4975
|
+
if (!st) return [];
|
|
4976
|
+
const files = [];
|
|
4977
|
+
await walkFiles(host2, target, files, (name) => /\.json$/i.test(name));
|
|
4978
|
+
const out = [];
|
|
4979
|
+
for (const file of files) {
|
|
4980
|
+
if (st.type !== "file" && !/[\\/]chatSessions[\\/][^\\/]+\.json$/i.test(file.path)) continue;
|
|
4981
|
+
const fst = await host2.stat(file.path);
|
|
4982
|
+
if (!fst) continue;
|
|
4983
|
+
const workspacePath = copilotVscodeWorkspacePath(file.path);
|
|
4984
|
+
const workspace = workspacePath ? readCopilotVscodeWorkspace(await host2.readText(workspacePath)) : null;
|
|
4985
|
+
const entries = await probeSource(bm, "copilot-vscode", file.path, fileFingerprint(fst), async () => {
|
|
4986
|
+
const session = readCopilotVscodeSession(await host2.readText(file.path));
|
|
4987
|
+
if (!session || !session.requests.length) return [];
|
|
4988
|
+
const info = copilotVscodeMetadata(session);
|
|
4989
|
+
return [makeEntry({
|
|
4990
|
+
format: "copilot-vscode",
|
|
4991
|
+
sessionId: info.id,
|
|
4992
|
+
title: info.title,
|
|
4993
|
+
cwd: info.cwd,
|
|
4994
|
+
project: projectFromRecord(info.cwd, () => null),
|
|
4995
|
+
createdAt: info.createdAt,
|
|
4996
|
+
lastActiveAt: info.lastActiveAt ?? fst.mtimeMs,
|
|
4997
|
+
sourcePath: file.path
|
|
4998
|
+
})];
|
|
4999
|
+
});
|
|
5000
|
+
const annotated = entries.map((entry) => {
|
|
5001
|
+
const cwd = entry.cwd || workspace;
|
|
5002
|
+
return cwd ? { ...entry, cwd, project: projectFromRecord(cwd, () => null) } : entry;
|
|
5003
|
+
});
|
|
5004
|
+
out.push(...annotated);
|
|
5005
|
+
await emitEach(emit, annotated);
|
|
5006
|
+
}
|
|
5007
|
+
return out;
|
|
5008
|
+
}
|
|
5009
|
+
var copilotVscodeSource = {
|
|
5010
|
+
format: "copilot-vscode",
|
|
5011
|
+
roots: copilotVscodeRoots,
|
|
5012
|
+
scan: scanCopilotVscode,
|
|
5013
|
+
matchFile: (lower) => /[\\/]chatsessions[\\/][^\\/]+\.json$/.test(lower) ? "only" : false,
|
|
5014
|
+
fileFallback: ["json"]
|
|
5015
|
+
};
|
|
5016
|
+
|
|
5017
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/copilot-cli.mjs
|
|
5018
|
+
function copilotCliRoots(home, env = {}, platform = process.platform) {
|
|
5019
|
+
if (isAbsoluteLike(env.COPILOT_HOME || "")) return [joinForPlatform(platform, env.COPILOT_HOME, "session-state")];
|
|
5020
|
+
return [joinForPlatform(platform, home, ".copilot", "session-state")];
|
|
5021
|
+
}
|
|
5022
|
+
async function scanCopilotCli(host2, target, { bm, emit }) {
|
|
5023
|
+
const st = await host2.stat(target);
|
|
5024
|
+
if (!st) return [];
|
|
5025
|
+
const files = [];
|
|
5026
|
+
await walkFiles(host2, target, files, (name) => /^events\.jsonl$/i.test(name));
|
|
5027
|
+
const out = [];
|
|
5028
|
+
for (const file of files) {
|
|
5029
|
+
const fst = await host2.stat(file.path);
|
|
5030
|
+
if (!fst) continue;
|
|
5031
|
+
const entries = await probeSource(bm, "copilot-cli", file.path, fileFingerprint(fst), async () => {
|
|
5032
|
+
const head = await host2.readHead(file.path, HEAD_MAX_BYTES);
|
|
5033
|
+
if (head === null || head === "") return [];
|
|
5034
|
+
const meta = copilotCliHeadMeta(parseJsonlHead(head));
|
|
5035
|
+
if (!meta) return [];
|
|
5036
|
+
return [makeEntry({
|
|
5037
|
+
format: "copilot-cli",
|
|
5038
|
+
sessionId: meta.id,
|
|
5039
|
+
title: meta.title ? normalizeTitle(meta.title) : null,
|
|
5040
|
+
cwd: meta.cwd,
|
|
5041
|
+
project: projectFromRecord(meta.cwd, () => null),
|
|
5042
|
+
createdAt: meta.createdAt,
|
|
5043
|
+
// 追加式事件流的 mtime 即最后一次写入时刻(头部窗口不含末尾时间戳)
|
|
5044
|
+
lastActiveAt: fst.mtimeMs,
|
|
5045
|
+
sourcePath: file.path
|
|
5046
|
+
})];
|
|
5047
|
+
});
|
|
5048
|
+
out.push(...entries);
|
|
5049
|
+
await emitEach(emit, entries);
|
|
5050
|
+
}
|
|
5051
|
+
return out;
|
|
5052
|
+
}
|
|
5053
|
+
var copilotCliSource = {
|
|
5054
|
+
format: "copilot-cli",
|
|
5055
|
+
roots: copilotCliRoots,
|
|
5056
|
+
scan: scanCopilotCli,
|
|
5057
|
+
matchFile: (lower) => /(^|[\\/])session-state[\\/][^\\/]+[\\/]events\.jsonl$/.test(lower) ? "only" : false,
|
|
5058
|
+
fileFallback: ["jsonl"]
|
|
5059
|
+
};
|
|
5060
|
+
|
|
5061
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/registry.mjs
|
|
3839
5062
|
var SOURCES = Object.freeze([
|
|
3840
5063
|
claudeSource,
|
|
3841
5064
|
codexSource,
|
|
@@ -3849,6 +5072,7 @@ var SOURCES = Object.freeze([
|
|
|
3849
5072
|
grokbuildSource,
|
|
3850
5073
|
openclawSource,
|
|
3851
5074
|
piSource,
|
|
5075
|
+
ompSource,
|
|
3852
5076
|
hermesSource,
|
|
3853
5077
|
kimiSource,
|
|
3854
5078
|
kilocodeSource,
|
|
@@ -3864,8 +5088,11 @@ var SOURCES = Object.freeze([
|
|
|
3864
5088
|
crushSource,
|
|
3865
5089
|
teleagentSource,
|
|
3866
5090
|
traeSource,
|
|
5091
|
+
doubaoSource,
|
|
3867
5092
|
vibeSource,
|
|
3868
|
-
dshSource
|
|
5093
|
+
dshSource,
|
|
5094
|
+
copilotVscodeSource,
|
|
5095
|
+
copilotCliSource
|
|
3869
5096
|
]);
|
|
3870
5097
|
var FORMATS = SOURCES.map((s) => s.format);
|
|
3871
5098
|
var BY_FORMAT = new Map(SOURCES.map((s) => [s.format, s]));
|
|
@@ -3876,7 +5103,7 @@ function defaultRoots({ home = homedir3(), env = process.env } = {}) {
|
|
|
3876
5103
|
return Object.fromEntries(SOURCES.map((s) => [s.format, s.roots(home, env) ?? null]));
|
|
3877
5104
|
}
|
|
3878
5105
|
|
|
3879
|
-
// .codex-tmp/
|
|
5106
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/run-host.mjs
|
|
3880
5107
|
function memoize(fn) {
|
|
3881
5108
|
const cache = /* @__PURE__ */ new Map();
|
|
3882
5109
|
return (key) => {
|
|
@@ -3894,7 +5121,7 @@ function createRunHost(host2) {
|
|
|
3894
5121
|
return run;
|
|
3895
5122
|
}
|
|
3896
5123
|
|
|
3897
|
-
// .codex-tmp/
|
|
5124
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery/discover.mjs
|
|
3898
5125
|
async function scanFormat(host2, format, target, bm, emit, warnings) {
|
|
3899
5126
|
const source = sourceOf(format);
|
|
3900
5127
|
if (!source) return [];
|
|
@@ -3915,7 +5142,7 @@ function errorMessage(err2) {
|
|
|
3915
5142
|
return String(err2);
|
|
3916
5143
|
}
|
|
3917
5144
|
|
|
3918
|
-
// .codex-tmp/
|
|
5145
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/mimocode.mjs
|
|
3919
5146
|
var MIMOCODE_BG_TITLE_WHERE = [
|
|
3920
5147
|
"title LIKE 'checkpoint-writer:%'",
|
|
3921
5148
|
"title LIKE 'checkpoint writer:%'",
|
|
@@ -3931,7 +5158,7 @@ function readMimocodeDbSummaries(dbPath) {
|
|
|
3931
5158
|
return readOpencodeDbSummaries(dbPath, { where: "NOT (" + MIMOCODE_BG_TITLE_WHERE + ")" });
|
|
3932
5159
|
}
|
|
3933
5160
|
|
|
3934
|
-
// .codex-tmp/
|
|
5161
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/kilocode.mjs
|
|
3935
5162
|
function readKilocodeDbSummaries(dbPath) {
|
|
3936
5163
|
const where = readOptionalDb(dbPath, (db) => {
|
|
3937
5164
|
const sessionCols = columnsOf(db, "session");
|
|
@@ -3943,7 +5170,7 @@ function readKilocodeDbSummaries(dbPath) {
|
|
|
3943
5170
|
return readOpencodeDbSummaries(dbPath, { where });
|
|
3944
5171
|
}
|
|
3945
5172
|
|
|
3946
|
-
// .codex-tmp/
|
|
5173
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/zcode.mjs
|
|
3947
5174
|
function readZcodeDbSummaries(dbPath) {
|
|
3948
5175
|
return withReadOnlyDb(dbPath, (db) => {
|
|
3949
5176
|
const hasMessage = hasTable(db, "message");
|
|
@@ -3960,7 +5187,7 @@ function readZcodeDbSummaries(dbPath) {
|
|
|
3960
5187
|
});
|
|
3961
5188
|
}
|
|
3962
5189
|
|
|
3963
|
-
// .codex-tmp/
|
|
5190
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/hermes.mjs
|
|
3964
5191
|
function readHermesDbSummaries(dbPath) {
|
|
3965
5192
|
return readOptionalDb(dbPath, (db) => {
|
|
3966
5193
|
if (!hasTable(db, "sessions")) return null;
|
|
@@ -3994,8 +5221,8 @@ function pickCol(cols, ...names) {
|
|
|
3994
5221
|
return void 0;
|
|
3995
5222
|
}
|
|
3996
5223
|
|
|
3997
|
-
// .codex-tmp/
|
|
3998
|
-
import { dirname, join as
|
|
5224
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/cline.mjs
|
|
5225
|
+
import { dirname, join as join15 } from "node:path";
|
|
3999
5226
|
var timeOf = (v) => parseTimeMs(v, { truncSeconds: true });
|
|
4000
5227
|
function metadataTitle(raw) {
|
|
4001
5228
|
if (typeof raw !== "string" || !raw) return "";
|
|
@@ -4011,7 +5238,7 @@ function readClineDb(dbPath) {
|
|
|
4011
5238
|
const cols = columnsOf(db, "sessions");
|
|
4012
5239
|
if (!cols.has("session_id")) return null;
|
|
4013
5240
|
const pick = (row, name) => cols.has(name) ? row[name] : void 0;
|
|
4014
|
-
const sessionsDir =
|
|
5241
|
+
const sessionsDir = join15(dirname(dirname(dbPath)), "sessions");
|
|
4015
5242
|
const out = [];
|
|
4016
5243
|
for (const row of db.prepare("SELECT * FROM sessions ORDER BY rowid DESC").all()) {
|
|
4017
5244
|
const id = typeof row.session_id === "string" && row.session_id ? row.session_id : null;
|
|
@@ -4037,7 +5264,7 @@ function readClineDb(dbPath) {
|
|
|
4037
5264
|
});
|
|
4038
5265
|
}
|
|
4039
5266
|
|
|
4040
|
-
// .codex-tmp/
|
|
5267
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/goose.mjs
|
|
4041
5268
|
function gooseTextTime(v) {
|
|
4042
5269
|
if (typeof v !== "string" || !v) return null;
|
|
4043
5270
|
const iso = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(v) ? v.replace(" ", "T") + "Z" : v;
|
|
@@ -4077,7 +5304,7 @@ function readGooseSessions(dbPath) {
|
|
|
4077
5304
|
return readOptionalDb(dbPath, gooseRows, (_db, read) => read.rows.map((row) => summaryOf(row, read.scols)));
|
|
4078
5305
|
}
|
|
4079
5306
|
|
|
4080
|
-
// .codex-tmp/
|
|
5307
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/zed.mjs
|
|
4081
5308
|
function zedRows(db) {
|
|
4082
5309
|
const tables = tableNames(db);
|
|
4083
5310
|
if (tables.size !== 1 || !tables.has("threads")) return null;
|
|
@@ -4106,7 +5333,7 @@ function readZedThreads(dbPath) {
|
|
|
4106
5333
|
});
|
|
4107
5334
|
}
|
|
4108
5335
|
|
|
4109
|
-
// .codex-tmp/
|
|
5336
|
+
// .codex-tmp/chat-import-0263/package/lib/sources/crush.mjs
|
|
4110
5337
|
function crushRows(db) {
|
|
4111
5338
|
const tables = tableNames(db);
|
|
4112
5339
|
if (!tables.has("sessions") || !tables.has("messages") || !tables.has("read_files")) return null;
|
|
@@ -4130,7 +5357,7 @@ function readCrushSessions(dbPath) {
|
|
|
4130
5357
|
})));
|
|
4131
5358
|
}
|
|
4132
5359
|
|
|
4133
|
-
// .codex-tmp/
|
|
5360
|
+
// .codex-tmp/chat-import-0263/package/lib/discovery-host.mjs
|
|
4134
5361
|
var DB_SUMMARY_READERS = {
|
|
4135
5362
|
// opencode 与 teleagent 无发现期过滤(teleagent 是 opencode 派生、schema 同构)
|
|
4136
5363
|
opencode: (dbPath) => readOpencodeDbSummaries(dbPath).map(pickSummary),
|
|
@@ -4194,6 +5421,16 @@ var DB_SUMMARY_READERS = {
|
|
|
4194
5421
|
directory: s.directory,
|
|
4195
5422
|
createdAt: s.createdAt,
|
|
4196
5423
|
lastActiveAt: s.lastActiveAt
|
|
5424
|
+
})),
|
|
5425
|
+
// doubao:库是 Chromium IndexedDB 的 LevelDB 目录。摘要与导入口径必须一致(只列本地确实
|
|
5426
|
+
// 有正文的会话)——另写一个「只读会话列表」的廉价路径会把没有正文的会话也列出来,
|
|
5427
|
+
// 面板上点进去才发现导不了。读不到目录 / 不是这个库 → null。
|
|
5428
|
+
doubao: (dbPath) => mapRows(readDoubaoSessionSummaries(dbPath), (s) => ({
|
|
5429
|
+
id: s.id,
|
|
5430
|
+
title: s.title,
|
|
5431
|
+
directory: null,
|
|
5432
|
+
createdAt: s.createdAt,
|
|
5433
|
+
lastActiveAt: s.lastActiveAt
|
|
4197
5434
|
}))
|
|
4198
5435
|
};
|
|
4199
5436
|
var DB_SUMMARY_FORMATS = Object.freeze(Object.keys(DB_SUMMARY_READERS));
|
|
@@ -4214,9 +5451,9 @@ function pickSummary(s) {
|
|
|
4214
5451
|
import { stat, readdir as readdir2, readFile as readFile2, open } from "node:fs/promises";
|
|
4215
5452
|
import { createReadStream } from "node:fs";
|
|
4216
5453
|
import { createInterface } from "node:readline";
|
|
4217
|
-
import { join as
|
|
5454
|
+
import { join as join16, resolve } from "node:path";
|
|
4218
5455
|
import { homedir as homedir4 } from "node:os";
|
|
4219
|
-
var expand = (path) => resolve(path.startsWith("~/") || path.startsWith("~\\") ?
|
|
5456
|
+
var expand = (path) => resolve(path.startsWith("~/") || path.startsWith("~\\") ? join16(homedir4(), path.slice(2)) : path);
|
|
4220
5457
|
async function missingAsNull(read) {
|
|
4221
5458
|
try {
|
|
4222
5459
|
return await read();
|
|
@@ -4247,7 +5484,7 @@ var host = {
|
|
|
4247
5484
|
readDir: (path) => missingAsNull(async () => (await readdir2(expand(path), { withFileTypes: true })).map((e) => ({
|
|
4248
5485
|
name: e.name,
|
|
4249
5486
|
type: e.isDirectory() ? "directory" : "file",
|
|
4250
|
-
path:
|
|
5487
|
+
path: join16(expand(path), e.name)
|
|
4251
5488
|
}))),
|
|
4252
5489
|
readText: (path) => missingAsNull(() => readFile2(expand(path), "utf8")),
|
|
4253
5490
|
readHead: async (path, cap = 256 * 1024) => (await windowBytes(path, cap))?.toString("utf8") ?? null,
|