@alsdd/t3-import 0.0.0-stage → 0.1.1-alsd.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +141 -2
- package/assets/fork-demo.gif +0 -0
- package/assets/fork-demo.png +0 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +399 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/checkpoint.d.ts +25 -0
- package/dist/core/checkpoint.js +82 -0
- package/dist/core/checkpoint.js.map +1 -0
- package/dist/core/errors.d.ts +12 -0
- package/dist/core/errors.js +17 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/jsonl.d.ts +7 -0
- package/dist/core/jsonl.js +37 -0
- package/dist/core/jsonl.js.map +1 -0
- package/dist/core/providers.d.ts +6 -0
- package/dist/core/providers.js +17 -0
- package/dist/core/providers.js.map +1 -0
- package/dist/core/types.d.ts +247 -0
- package/dist/core/types.js +4 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/util.d.ts +14 -0
- package/dist/core/util.js +61 -0
- package/dist/core/util.js.map +1 -0
- package/dist/sources/claude.d.ts +6 -0
- package/dist/sources/claude.js +576 -0
- package/dist/sources/claude.js.map +1 -0
- package/dist/sources/codex.d.ts +11 -0
- package/dist/sources/codex.js +603 -0
- package/dist/sources/codex.js.map +1 -0
- package/dist/sources/codexAppServer.d.ts +24 -0
- package/dist/sources/codexAppServer.js +190 -0
- package/dist/sources/codexAppServer.js.map +1 -0
- package/dist/sources/files.d.ts +1 -0
- package/dist/sources/files.js +24 -0
- package/dist/sources/files.js.map +1 -0
- package/dist/sources/index.d.ts +3 -0
- package/dist/sources/index.js +15 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/opencode.d.ts +6 -0
- package/dist/sources/opencode.js +443 -0
- package/dist/sources/opencode.js.map +1 -0
- package/dist/target/cache.d.ts +14 -0
- package/dist/target/cache.js +155 -0
- package/dist/target/cache.js.map +1 -0
- package/dist/target/config.d.ts +22 -0
- package/dist/target/config.js +90 -0
- package/dist/target/config.js.map +1 -0
- package/dist/target/destination.d.ts +21 -0
- package/dist/target/destination.js +77 -0
- package/dist/target/destination.js.map +1 -0
- package/dist/target/importer.d.ts +86 -0
- package/dist/target/importer.js +597 -0
- package/dist/target/importer.js.map +1 -0
- package/dist/target/launch.d.ts +6 -0
- package/dist/target/launch.js +77 -0
- package/dist/target/launch.js.map +1 -0
- package/dist/target/ledger.d.ts +35 -0
- package/dist/target/ledger.js +174 -0
- package/dist/target/ledger.js.map +1 -0
- package/dist/target/reconciliation.d.ts +60 -0
- package/dist/target/reconciliation.js +259 -0
- package/dist/target/reconciliation.js.map +1 -0
- package/dist/target/replace.d.ts +9 -0
- package/dist/target/replace.js +341 -0
- package/dist/target/replace.js.map +1 -0
- package/dist/target/schema.d.ts +22 -0
- package/dist/target/schema.js +108 -0
- package/dist/target/schema.js.map +1 -0
- package/dist/target/sync.d.ts +34 -0
- package/dist/target/sync.js +879 -0
- package/dist/target/sync.js.map +1 -0
- package/dist/target/syncAll.d.ts +4 -0
- package/dist/target/syncAll.js +98 -0
- package/dist/target/syncAll.js.map +1 -0
- package/dist/target/v2.d.ts +18 -0
- package/dist/target/v2.js +267 -0
- package/dist/target/v2.js.map +1 -0
- package/dist/target/v2Profiles.d.ts +5 -0
- package/dist/target/v2Profiles.js +14 -0
- package/dist/target/v2Profiles.js.map +1 -0
- package/dist/tui.d.ts +49 -0
- package/dist/tui.js +560 -0
- package/dist/tui.js.map +1 -0
- package/package.json +93 -4
- package/vendor/t3-v010/LICENSE +21 -0
- package/vendor/t3-v010/THIRD-PARTY-NOTICES.txt +2274 -0
- package/vendor/t3-v010/reference.json +6 -0
- package/vendor/t3-v010/runtime.mjs +60364 -0
- package/vendor/t3-v010/schema-columns.json +568 -0
- package/vendor/t3-v011/LICENSE +21 -0
- package/vendor/t3-v011/THIRD-PARTY-NOTICES.txt +2274 -0
- package/vendor/t3-v011/reference.json +6 -0
- package/vendor/t3-v011/runtime.mjs +60993 -0
- package/vendor/t3-v011/schema-columns.json +526 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CanonicalTerminalTurnStatus, CanonicalThread, CanonicalTurn } from "./types.js";
|
|
2
|
+
export interface TurnCheckpointV1 {
|
|
3
|
+
id: string;
|
|
4
|
+
hash: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ImportCheckpointV1 {
|
|
7
|
+
version: 1;
|
|
8
|
+
turns: TurnCheckpointV1[];
|
|
9
|
+
}
|
|
10
|
+
export interface TurnCheckpointV2 {
|
|
11
|
+
id: string;
|
|
12
|
+
status: CanonicalTerminalTurnStatus;
|
|
13
|
+
terminalReason?: string;
|
|
14
|
+
terminalError?: string;
|
|
15
|
+
hash: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ImportCheckpointV2 {
|
|
18
|
+
version: 2;
|
|
19
|
+
turns: TurnCheckpointV2[];
|
|
20
|
+
}
|
|
21
|
+
export type ImportCheckpoint = ImportCheckpointV1 | ImportCheckpointV2;
|
|
22
|
+
export declare function legacyTurnSemanticHash(turn: CanonicalTurn): string;
|
|
23
|
+
export declare function turnSemanticHash(turn: CanonicalTurn): string;
|
|
24
|
+
export declare function checkpointForThread(thread: CanonicalThread): ImportCheckpointV2;
|
|
25
|
+
export declare function parseCheckpoint(value: string | null | undefined): ImportCheckpoint | undefined;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { isTerminalTurn } from "./types.js";
|
|
2
|
+
import { sha256 } from "./util.js";
|
|
3
|
+
function canonicalJson(value) {
|
|
4
|
+
if (Array.isArray(value))
|
|
5
|
+
return `[${value.map(canonicalJson).join(",")}]`;
|
|
6
|
+
if (value && typeof value === "object") {
|
|
7
|
+
const record = value;
|
|
8
|
+
return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(",")}}`;
|
|
9
|
+
}
|
|
10
|
+
return JSON.stringify(value);
|
|
11
|
+
}
|
|
12
|
+
function turnHashPayload(turn) {
|
|
13
|
+
return {
|
|
14
|
+
id: turn.id,
|
|
15
|
+
startedAt: turn.startedAt,
|
|
16
|
+
completedAt: turn.completedAt ?? null,
|
|
17
|
+
user: {
|
|
18
|
+
sourceId: turn.user.sourceId,
|
|
19
|
+
text: turn.user.text,
|
|
20
|
+
timestamp: turn.user.timestamp,
|
|
21
|
+
attachments: turn.user.attachments.map((attachment) => ({
|
|
22
|
+
sourceId: attachment.sourceId,
|
|
23
|
+
name: attachment.name,
|
|
24
|
+
mimeType: attachment.mimeType,
|
|
25
|
+
sizeBytes: attachment.sizeBytes,
|
|
26
|
+
remoteUrl: attachment.remoteUrl ?? null,
|
|
27
|
+
contentHash: attachment.data ? sha256(attachment.data) : null,
|
|
28
|
+
})),
|
|
29
|
+
},
|
|
30
|
+
assistant: turn.assistant.map((message) => ({ sourceId: message.sourceId, text: message.text, timestamp: message.timestamp })),
|
|
31
|
+
activities: turn.activities.map((activity) => ({ sourceId: activity.sourceId, kind: activity.kind, tone: activity.tone, summary: activity.summary, timestamp: activity.timestamp, payload: activity.payload })),
|
|
32
|
+
plans: turn.plans.map((plan) => ({ sourceId: plan.sourceId, markdown: plan.markdown, timestamp: plan.timestamp })),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function legacyTurnSemanticHash(turn) {
|
|
36
|
+
return sha256(canonicalJson({
|
|
37
|
+
...turnHashPayload(turn),
|
|
38
|
+
complete: true,
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
export function turnSemanticHash(turn) {
|
|
42
|
+
return sha256(canonicalJson({
|
|
43
|
+
...turnHashPayload(turn),
|
|
44
|
+
status: turn.status,
|
|
45
|
+
terminalReason: turn.terminalReason ?? null,
|
|
46
|
+
terminalError: turn.terminalError ?? null,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
export function checkpointForThread(thread) {
|
|
50
|
+
return {
|
|
51
|
+
version: 2,
|
|
52
|
+
turns: thread.turns.filter(isTerminalTurn).map((turn) => ({
|
|
53
|
+
id: turn.id,
|
|
54
|
+
status: turn.status,
|
|
55
|
+
...(turn.terminalReason ? { terminalReason: turn.terminalReason } : {}),
|
|
56
|
+
...(turn.terminalError ? { terminalError: turn.terminalError } : {}),
|
|
57
|
+
hash: turnSemanticHash(turn),
|
|
58
|
+
})),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function parseCheckpoint(value) {
|
|
62
|
+
if (!value)
|
|
63
|
+
return undefined;
|
|
64
|
+
try {
|
|
65
|
+
const parsed = JSON.parse(value);
|
|
66
|
+
if (!Array.isArray(parsed.turns))
|
|
67
|
+
return undefined;
|
|
68
|
+
if (!parsed.turns.every((turn) => typeof turn.id === "string" && typeof turn.hash === "string"))
|
|
69
|
+
return undefined;
|
|
70
|
+
if (parsed.version === 1)
|
|
71
|
+
return parsed;
|
|
72
|
+
if (parsed.version !== 2)
|
|
73
|
+
return undefined;
|
|
74
|
+
if (!parsed.turns.every((turn) => ["completed", "interrupted", "failed"].includes(turn.status)))
|
|
75
|
+
return undefined;
|
|
76
|
+
return parsed;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=checkpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/core/checkpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ExitCode = 2 | 3 | 4 | 5 | 6 | 7;
|
|
2
|
+
export declare class ImporterError extends Error {
|
|
3
|
+
readonly exitCode: ExitCode;
|
|
4
|
+
readonly details?: unknown | undefined;
|
|
5
|
+
constructor(message: string, exitCode: ExitCode, details?: unknown | undefined);
|
|
6
|
+
}
|
|
7
|
+
export declare const usageError: (message: string) => ImporterError;
|
|
8
|
+
export declare const compatibilityError: (message: string) => ImporterError;
|
|
9
|
+
export declare const safetyError: (message: string) => ImporterError;
|
|
10
|
+
export declare const sourceError: (message: string, details?: unknown) => ImporterError;
|
|
11
|
+
export declare const writeError: (message: string, details?: unknown) => ImporterError;
|
|
12
|
+
export declare const syncConflictError: (message: string, details?: unknown) => ImporterError;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class ImporterError extends Error {
|
|
2
|
+
exitCode;
|
|
3
|
+
details;
|
|
4
|
+
constructor(message, exitCode, details) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.exitCode = exitCode;
|
|
7
|
+
this.details = details;
|
|
8
|
+
this.name = "ImporterError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export const usageError = (message) => new ImporterError(message, 2);
|
|
12
|
+
export const compatibilityError = (message) => new ImporterError(message, 3);
|
|
13
|
+
export const safetyError = (message) => new ImporterError(message, 4);
|
|
14
|
+
export const sourceError = (message, details) => new ImporterError(message, 5, details);
|
|
15
|
+
export const writeError = (message, details) => new ImporterError(message, 6, details);
|
|
16
|
+
export const syncConflictError = (message, details) => new ImporterError(message, 7, details);
|
|
17
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAc,SAAQ,KAAK;IAG3B;IACA;IAHX,YACE,OAAe,EACN,QAAkB,EAClB,OAAiB;QAE1B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHN,aAAQ,GAAR,QAAQ,CAAU;QAClB,YAAO,GAAP,OAAO,CAAU;QAG1B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACrF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,OAAiB,EAAE,EAAE,CAChE,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,OAAiB,EAAE,EAAE,CAC/D,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACzC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAE,OAAiB,EAAE,EAAE,CACtE,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createReadStream, statSync } from "node:fs";
|
|
2
|
+
import { createInterface } from "node:readline";
|
|
3
|
+
import { sha256 } from "./util.js";
|
|
4
|
+
async function readOnce(path) {
|
|
5
|
+
const before = statSync(path);
|
|
6
|
+
const rows = [];
|
|
7
|
+
const hashParts = [];
|
|
8
|
+
const lines = createInterface({ input: createReadStream(path, { encoding: "utf8" }), crlfDelay: Infinity });
|
|
9
|
+
for await (const line of lines) {
|
|
10
|
+
if (!line.trim())
|
|
11
|
+
continue;
|
|
12
|
+
hashParts.push(line, "\n");
|
|
13
|
+
try {
|
|
14
|
+
rows.push(JSON.parse(line));
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
throw new Error(`Invalid JSONL in ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const after = statSync(path);
|
|
21
|
+
if (before.size !== after.size || before.mtimeMs !== after.mtimeMs) {
|
|
22
|
+
throw new Error("SOURCE_CHANGED_DURING_READ");
|
|
23
|
+
}
|
|
24
|
+
return { rows, fingerprint: sha256(hashParts.join("")), mtimeMs: after.mtimeMs, size: after.size };
|
|
25
|
+
}
|
|
26
|
+
export async function readStableJsonl(path) {
|
|
27
|
+
try {
|
|
28
|
+
return await readOnce(path);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (error instanceof Error && error.message === "SOURCE_CHANGED_DURING_READ") {
|
|
32
|
+
return readOnce(path);
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=jsonl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../../src/core/jsonl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AASnC,KAAK,UAAU,QAAQ,CAAC,IAAY;IAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5G,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,SAAS;QAC3B,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACzG,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AACrG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,4BAA4B,EAAE,CAAC;YAC7E,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CanonicalThread } from "./types.js";
|
|
2
|
+
export declare const sourceNames: readonly ["codex", "claude", "opencode"];
|
|
3
|
+
export type ProviderDriver = "codex" | "claudeAgent" | "opencode";
|
|
4
|
+
export declare function sourceDriver(source: string): ProviderDriver;
|
|
5
|
+
export declare function sourceFromDriver(driver: string): typeof sourceNames[number] | undefined;
|
|
6
|
+
export declare function nativeSessionId(thread: CanonicalThread): string | undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { stringValue } from "./util.js";
|
|
2
|
+
import { usageError } from "./errors.js";
|
|
3
|
+
export const sourceNames = ["codex", "claude", "opencode"];
|
|
4
|
+
const drivers = { codex: "codex", claude: "claudeAgent", opencode: "opencode" };
|
|
5
|
+
export function sourceDriver(source) {
|
|
6
|
+
if (!Object.hasOwn(drivers, source))
|
|
7
|
+
throw usageError(`Unsupported source: ${source}`);
|
|
8
|
+
return drivers[source];
|
|
9
|
+
}
|
|
10
|
+
export function sourceFromDriver(driver) {
|
|
11
|
+
return sourceNames.find((source) => sourceDriver(source) === driver);
|
|
12
|
+
}
|
|
13
|
+
export function nativeSessionId(thread) {
|
|
14
|
+
const key = thread.source === "codex" ? "threadId" : thread.source === "claude" ? "resume" : "sessionId";
|
|
15
|
+
return stringValue(thread.resumeCursor?.[key]);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/core/providers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAC;AAEpE,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAW,CAAC;AACzF,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC;QAAE,MAAM,UAAU,CAAC,uBAAuB,MAAM,EAAE,CAAC,CAAC;IACvF,OAAO,OAAO,CAAC,MAAoC,CAAC,CAAC;AACvD,CAAC;AACD,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,CAAC;AACvE,CAAC;AACD,MAAM,UAAU,eAAe,CAAC,MAAuB;IACrD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC;IACzG,OAAO,WAAW,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import type { sourceNames } from "./providers.js";
|
|
2
|
+
export type SourceName = typeof sourceNames[number];
|
|
3
|
+
export type ActivityTone = "info" | "tool" | "approval" | "error";
|
|
4
|
+
export type CanonicalTurnStatus = "completed" | "interrupted" | "failed" | "inProgress";
|
|
5
|
+
export type CanonicalTerminalTurnStatus = Exclude<CanonicalTurnStatus, "inProgress">;
|
|
6
|
+
export interface SourceSummary {
|
|
7
|
+
source: SourceName;
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
workspace: string;
|
|
11
|
+
path: string;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
updatedAt: string;
|
|
14
|
+
status: "complete" | "incomplete";
|
|
15
|
+
branches: number;
|
|
16
|
+
parentId?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface SourceAttachment {
|
|
19
|
+
sourceId: string;
|
|
20
|
+
name: string;
|
|
21
|
+
mimeType: string;
|
|
22
|
+
sizeBytes: number;
|
|
23
|
+
path?: string;
|
|
24
|
+
data?: Buffer;
|
|
25
|
+
remoteUrl?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface CanonicalMessage {
|
|
28
|
+
sourceId: string;
|
|
29
|
+
role: "user" | "assistant";
|
|
30
|
+
text: string;
|
|
31
|
+
timestamp: string;
|
|
32
|
+
attachments: SourceAttachment[];
|
|
33
|
+
}
|
|
34
|
+
export interface CanonicalActivity {
|
|
35
|
+
sourceId: string;
|
|
36
|
+
tone: ActivityTone;
|
|
37
|
+
kind: string;
|
|
38
|
+
summary: string;
|
|
39
|
+
payload: Record<string, unknown>;
|
|
40
|
+
timestamp: string;
|
|
41
|
+
}
|
|
42
|
+
export interface CanonicalPlan {
|
|
43
|
+
sourceId: string;
|
|
44
|
+
markdown: string;
|
|
45
|
+
timestamp: string;
|
|
46
|
+
}
|
|
47
|
+
export interface CanonicalTurn {
|
|
48
|
+
id: string;
|
|
49
|
+
startedAt: string;
|
|
50
|
+
completedAt?: string;
|
|
51
|
+
status: CanonicalTurnStatus;
|
|
52
|
+
terminalReason?: string;
|
|
53
|
+
terminalError?: string;
|
|
54
|
+
user: CanonicalMessage;
|
|
55
|
+
assistant: CanonicalMessage[];
|
|
56
|
+
activities: CanonicalActivity[];
|
|
57
|
+
plans: CanonicalPlan[];
|
|
58
|
+
}
|
|
59
|
+
export interface CanonicalThread {
|
|
60
|
+
source: SourceName;
|
|
61
|
+
sourceSessionId: string;
|
|
62
|
+
sourceKey: string;
|
|
63
|
+
leafId?: string;
|
|
64
|
+
currentBranch: boolean;
|
|
65
|
+
title: string;
|
|
66
|
+
workspace: string;
|
|
67
|
+
gitBranch?: string;
|
|
68
|
+
model: string;
|
|
69
|
+
modelOptions?: Array<{
|
|
70
|
+
id: string;
|
|
71
|
+
value: string | boolean;
|
|
72
|
+
}>;
|
|
73
|
+
effort?: string;
|
|
74
|
+
createdAt: string;
|
|
75
|
+
updatedAt: string;
|
|
76
|
+
turns: CanonicalTurn[];
|
|
77
|
+
ignoredInProgressTurns?: number;
|
|
78
|
+
resumeCursor?: Record<string, unknown>;
|
|
79
|
+
warnings: string[];
|
|
80
|
+
}
|
|
81
|
+
export interface CanonicalConversation {
|
|
82
|
+
summary: SourceSummary;
|
|
83
|
+
threads: CanonicalThread[];
|
|
84
|
+
fingerprint: string;
|
|
85
|
+
}
|
|
86
|
+
export interface DiscoveryOptions {
|
|
87
|
+
workspace?: string;
|
|
88
|
+
since?: Date;
|
|
89
|
+
includeIncomplete?: boolean;
|
|
90
|
+
}
|
|
91
|
+
export interface SourceAdapter {
|
|
92
|
+
readonly name: SourceName;
|
|
93
|
+
discover(options: DiscoveryOptions): Promise<SourceSummary[]>;
|
|
94
|
+
load(summary: SourceSummary, options: DiscoveryOptions): Promise<CanonicalConversation>;
|
|
95
|
+
dispose?(): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
export interface TargetPaths {
|
|
98
|
+
t3Home: string;
|
|
99
|
+
stateDir: string;
|
|
100
|
+
dbPath: string;
|
|
101
|
+
attachmentsDir: string;
|
|
102
|
+
runtimeStatePath: string;
|
|
103
|
+
settingsPath: string;
|
|
104
|
+
}
|
|
105
|
+
export interface ImportSelection {
|
|
106
|
+
conversation: CanonicalConversation;
|
|
107
|
+
resume: boolean;
|
|
108
|
+
}
|
|
109
|
+
export interface ImportItemResult {
|
|
110
|
+
source: SourceName;
|
|
111
|
+
sourceId: string;
|
|
112
|
+
sourceKey: string;
|
|
113
|
+
status: "imported" | "already-imported" | "dry-run";
|
|
114
|
+
threadId: string;
|
|
115
|
+
projectId: string;
|
|
116
|
+
sourceWorkspace?: string;
|
|
117
|
+
workingDirectory?: string;
|
|
118
|
+
title: string;
|
|
119
|
+
turns: number;
|
|
120
|
+
messages: number;
|
|
121
|
+
activities: number;
|
|
122
|
+
events: number;
|
|
123
|
+
attachments: number;
|
|
124
|
+
resumable: boolean;
|
|
125
|
+
warnings: string[];
|
|
126
|
+
sequence?: {
|
|
127
|
+
first: number;
|
|
128
|
+
last: number;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export interface ImportRunResult {
|
|
132
|
+
schemaVersion: 1;
|
|
133
|
+
status: "imported" | "dry-run" | "already-imported" | "mixed";
|
|
134
|
+
target: string;
|
|
135
|
+
migration: number;
|
|
136
|
+
backup: string | null;
|
|
137
|
+
cache?: CacheResetResult;
|
|
138
|
+
results: ImportItemResult[];
|
|
139
|
+
warnings: string[];
|
|
140
|
+
}
|
|
141
|
+
export type SyncItemStatus = "synced" | "up-to-date" | "history-diverged" | "branch-sync-unsupported" | "target-missing" | "not-imported" | "dry-run";
|
|
142
|
+
export type SyncTitleAction = "updated" | "unchanged" | "preserved-local";
|
|
143
|
+
export interface SyncItemResult {
|
|
144
|
+
source: SourceName;
|
|
145
|
+
sourceId: string;
|
|
146
|
+
sourceKey: string;
|
|
147
|
+
status: SyncItemStatus;
|
|
148
|
+
threadId?: string;
|
|
149
|
+
projectId?: string;
|
|
150
|
+
title: string;
|
|
151
|
+
turnsAdded: number;
|
|
152
|
+
turnsAdopted: number;
|
|
153
|
+
events: number;
|
|
154
|
+
attachments: number;
|
|
155
|
+
titleAction: SyncTitleAction;
|
|
156
|
+
resumable: boolean;
|
|
157
|
+
warnings: string[];
|
|
158
|
+
sequence?: {
|
|
159
|
+
first: number;
|
|
160
|
+
last: number;
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
export interface SyncRunResult {
|
|
164
|
+
schemaVersion: 1;
|
|
165
|
+
status: "synced" | "up-to-date" | "dry-run" | "mixed" | "conflict";
|
|
166
|
+
target: string;
|
|
167
|
+
migration: number;
|
|
168
|
+
backup: string | null;
|
|
169
|
+
cache?: CacheResetResult;
|
|
170
|
+
results: SyncItemResult[];
|
|
171
|
+
warnings: string[];
|
|
172
|
+
hasConflicts: boolean;
|
|
173
|
+
}
|
|
174
|
+
export interface CacheResetResult {
|
|
175
|
+
status: "reset" | "not-found";
|
|
176
|
+
backup: string | null;
|
|
177
|
+
profile: string | null;
|
|
178
|
+
entries: string[];
|
|
179
|
+
warnings: string[];
|
|
180
|
+
}
|
|
181
|
+
export interface ReplaceSelection {
|
|
182
|
+
conversation: CanonicalConversation;
|
|
183
|
+
}
|
|
184
|
+
export type ReplaceItemStatus = "replaced" | "already-current" | "not-imported" | "active-source" | "branch-replace-unsupported" | "target-missing" | "dry-run";
|
|
185
|
+
export interface ReplaceItemResult {
|
|
186
|
+
source: SourceName;
|
|
187
|
+
sourceId: string;
|
|
188
|
+
sourceKey: string;
|
|
189
|
+
status: ReplaceItemStatus;
|
|
190
|
+
oldThreadId?: string;
|
|
191
|
+
newThreadId?: string;
|
|
192
|
+
projectId?: string;
|
|
193
|
+
title: string;
|
|
194
|
+
turns: number;
|
|
195
|
+
events: number;
|
|
196
|
+
attachments: number;
|
|
197
|
+
resumeTransferred: boolean;
|
|
198
|
+
oldThreadIds?: string[];
|
|
199
|
+
warnings: string[];
|
|
200
|
+
sequence?: {
|
|
201
|
+
first: number;
|
|
202
|
+
last: number;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
export interface ReplaceRunResult {
|
|
206
|
+
schemaVersion: 1;
|
|
207
|
+
status: "replaced" | "already-current" | "dry-run" | "mixed" | "conflict";
|
|
208
|
+
target: string;
|
|
209
|
+
migration: number;
|
|
210
|
+
backup: string | null;
|
|
211
|
+
cache?: CacheResetResult;
|
|
212
|
+
results: ReplaceItemResult[];
|
|
213
|
+
warnings: string[];
|
|
214
|
+
hasConflicts: boolean;
|
|
215
|
+
}
|
|
216
|
+
export interface ConversationReplacePreview {
|
|
217
|
+
sourceId: string;
|
|
218
|
+
status: Exclude<ReplaceItemStatus, "replaced" | "dry-run"> | "replaceable";
|
|
219
|
+
selectable: boolean;
|
|
220
|
+
previouslyImported: boolean;
|
|
221
|
+
turns: number;
|
|
222
|
+
events: number;
|
|
223
|
+
attachments: number;
|
|
224
|
+
oldThreadId?: string;
|
|
225
|
+
oldThreadIds?: string[];
|
|
226
|
+
newThreadId?: string;
|
|
227
|
+
warnings: string[];
|
|
228
|
+
}
|
|
229
|
+
export interface SyncSelection {
|
|
230
|
+
conversation: CanonicalConversation;
|
|
231
|
+
}
|
|
232
|
+
export interface ConversationSyncPreview {
|
|
233
|
+
sourceId: string;
|
|
234
|
+
status: "new" | "active-only" | "syncable" | "up-to-date" | "history-diverged" | "branch-sync-unsupported" | "target-missing";
|
|
235
|
+
newTurns: number;
|
|
236
|
+
newCompletedTurns: number;
|
|
237
|
+
newInterruptedTurns: number;
|
|
238
|
+
newFailedTurns: number;
|
|
239
|
+
ignoredActiveTurns: number;
|
|
240
|
+
adoptedTurns: number;
|
|
241
|
+
titleChanged: boolean;
|
|
242
|
+
selectable: boolean;
|
|
243
|
+
previouslyImported: boolean;
|
|
244
|
+
threadId?: string;
|
|
245
|
+
warnings: string[];
|
|
246
|
+
}
|
|
247
|
+
export declare function isTerminalTurn(turn: CanonicalTurn): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAmRA,MAAM,UAAU,cAAc,CAAC,IAAmB;IAChD,OAAO,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type JsonObject = Record<string, unknown>;
|
|
2
|
+
export declare function isObject(value: unknown): value is JsonObject;
|
|
3
|
+
export declare function stringValue(value: unknown): string | undefined;
|
|
4
|
+
export declare function isoTimestamp(value: unknown, fallback: string): string;
|
|
5
|
+
export declare function sha256(value: string | Buffer): string;
|
|
6
|
+
export declare function deterministicUuid(value: string): string;
|
|
7
|
+
export declare function canonicalPath(input: string): string;
|
|
8
|
+
export declare function pathContains(parent: string, child: string): boolean;
|
|
9
|
+
export declare function truncate(value: string, limit?: number): string;
|
|
10
|
+
export declare function deriveTitle(text: string, fallback?: string): string;
|
|
11
|
+
export declare function sortStable<T extends {
|
|
12
|
+
timestamp: string;
|
|
13
|
+
sourceId: string;
|
|
14
|
+
}>(items: T[]): T[];
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { realpathSync } from "node:fs";
|
|
3
|
+
import { isAbsolute, normalize, resolve } from "node:path";
|
|
4
|
+
export function isObject(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
export function stringValue(value) {
|
|
8
|
+
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
9
|
+
}
|
|
10
|
+
export function isoTimestamp(value, fallback) {
|
|
11
|
+
if (typeof value !== "string" && typeof value !== "number")
|
|
12
|
+
return fallback;
|
|
13
|
+
const parsed = typeof value === "number" && value < 10_000_000_000
|
|
14
|
+
? new Date(value * 1_000)
|
|
15
|
+
: new Date(value);
|
|
16
|
+
return Number.isNaN(parsed.valueOf()) ? fallback : parsed.toISOString();
|
|
17
|
+
}
|
|
18
|
+
export function sha256(value) {
|
|
19
|
+
return createHash("sha256").update(value).digest("hex");
|
|
20
|
+
}
|
|
21
|
+
export function deterministicUuid(value) {
|
|
22
|
+
const bytes = createHash("sha256").update(value).digest().subarray(0, 16);
|
|
23
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x50;
|
|
24
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
25
|
+
const hex = bytes.toString("hex");
|
|
26
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
27
|
+
}
|
|
28
|
+
export function canonicalPath(input) {
|
|
29
|
+
const absolute = isAbsolute(input) ? normalize(input) : resolve(input);
|
|
30
|
+
let result = absolute;
|
|
31
|
+
try {
|
|
32
|
+
result = realpathSync.native(absolute);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Historical source workspaces can be missing; keep the normalized path.
|
|
36
|
+
}
|
|
37
|
+
result = result.replace(/[\\/]+$/u, "");
|
|
38
|
+
return process.platform === "win32" || process.platform === "darwin"
|
|
39
|
+
? result.toLowerCase()
|
|
40
|
+
: result;
|
|
41
|
+
}
|
|
42
|
+
export function pathContains(parent, child) {
|
|
43
|
+
const normalizedParent = canonicalPath(parent);
|
|
44
|
+
const normalizedChild = canonicalPath(child);
|
|
45
|
+
if (normalizedParent === normalizedChild)
|
|
46
|
+
return true;
|
|
47
|
+
const separator = process.platform === "win32" ? "\\" : "/";
|
|
48
|
+
return normalizedChild.startsWith(`${normalizedParent}${separator}`);
|
|
49
|
+
}
|
|
50
|
+
export function truncate(value, limit = 180) {
|
|
51
|
+
const normalized = value.trim();
|
|
52
|
+
return normalized.length <= limit ? normalized : `${normalized.slice(0, limit - 1)}…`;
|
|
53
|
+
}
|
|
54
|
+
export function deriveTitle(text, fallback = "Imported conversation") {
|
|
55
|
+
const line = text.split(/\r?\n/u).find((entry) => entry.trim().length > 0)?.trim() ?? fallback;
|
|
56
|
+
return truncate(line, 72);
|
|
57
|
+
}
|
|
58
|
+
export function sortStable(items) {
|
|
59
|
+
return items.sort((left, right) => left.timestamp.localeCompare(right.timestamp) || left.sourceId.localeCompare(right.sourceId));
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/core/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAI3D,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,QAAgB;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC5E,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,cAAc;QAChE,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACzB,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAsB;IAC3C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1E,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;AAC7G,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvE,IAAI,MAAM,GAAG,QAAQ,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;IAC3E,CAAC;IACD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACxC,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAClE,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE;QACtB,CAAC,CAAC,MAAM,CAAC;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,KAAa;IACxD,MAAM,gBAAgB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,eAAe,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,gBAAgB,KAAK,eAAe;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5D,OAAO,eAAe,CAAC,UAAU,CAAC,GAAG,gBAAgB,GAAG,SAAS,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,KAAK,GAAG,GAAG;IACjD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,QAAQ,GAAG,uBAAuB;IAC1E,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,QAAQ,CAAC;IAC/F,OAAO,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,UAAU,CAAoD,KAAU;IACtF,OAAO,KAAK,CAAC,IAAI,CACf,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAC9G,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CanonicalConversation, DiscoveryOptions, SourceAdapter, SourceSummary } from "../core/types.js";
|
|
2
|
+
export declare class ClaudeSource implements SourceAdapter {
|
|
3
|
+
readonly name: "claude";
|
|
4
|
+
discover(options: DiscoveryOptions): Promise<SourceSummary[]>;
|
|
5
|
+
load(summary: SourceSummary, options: DiscoveryOptions): Promise<CanonicalConversation>;
|
|
6
|
+
}
|