spiracha 1.1.0 → 1.1.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/AGENTS.md +3 -0
- package/README.md +14 -0
- package/apps/ui/dist/client/assets/{analytics-BjYaHqXk.js → analytics-CqWZmyV6.js} +1 -1
- package/apps/ui/dist/client/assets/{checkbox-wPoGG3of.js → checkbox-DXM4lkJq.js} +1 -1
- package/apps/ui/dist/client/assets/{data-table-6yDgAdtf.js → data-table-DnPYMPCD.js} +1 -1
- package/apps/ui/dist/client/assets/{delete-confirm-dialog-DJUAk7ha.js → delete-confirm-dialog-CcZaRX33.js} +1 -1
- package/apps/ui/dist/client/assets/{download-BhWd-Pm5.js → download-DOwxk-cG.js} +1 -1
- package/apps/ui/dist/client/assets/{es2015-BlyMI4CF.js → es2015-Bm0kEzx2.js} +1 -1
- package/apps/ui/dist/client/assets/{formatters-BxjZwWSE.js → formatters-C12LmYaa.js} +1 -1
- package/apps/ui/dist/client/assets/{index-T01rPkb4.js → index-DdJ7ahIt.js} +3 -3
- package/apps/ui/dist/client/assets/{input-B3YN8gzg.js → input-CEsI7EpI.js} +1 -1
- package/apps/ui/dist/client/assets/{metric-card-BWW7TWER.js → metric-card-9jwBF7rG.js} +1 -1
- package/apps/ui/dist/client/assets/{page-header-BZ8Gnxgs.js → page-header-Dr_h1CVv.js} +1 -1
- package/apps/ui/dist/client/assets/projects._project-uyNGnpjH.js +1 -0
- package/apps/ui/dist/client/assets/{projects._project-EfBhCHPY.js → projects._project-zoM8d2nH.js} +1 -1
- package/apps/ui/dist/client/assets/projects.index-D1CWVN-O.js +1 -0
- package/apps/ui/dist/client/assets/{projects.index-DzEZ4pAJ.js → projects.index-DukMuny6.js} +1 -1
- package/apps/ui/dist/client/assets/{routes-CWCCZykE.js → routes-Gr2Wwh83.js} +1 -1
- package/apps/ui/dist/client/assets/{select-DLXGsyZ4.js → select-CFim44gT.js} +1 -1
- package/apps/ui/dist/client/assets/{settings-b0Xthfae.js → settings-DqhyDxo2.js} +1 -1
- package/apps/ui/dist/client/assets/styles-CMrP9Jb4.css +1 -0
- package/apps/ui/dist/client/assets/{threads._threadId-CgtoCqTb.js → threads._threadId-DT75NiBa.js} +1 -1
- package/apps/ui/dist/client/assets/{threads._threadId-DBiDb38K.js → threads._threadId-Df5VXIuZ.js} +3 -3
- package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-C0V305Nt.js +99 -0
- package/apps/ui/dist/server/assets/{analytics-Br_fZB6a.js → analytics-BMxW_bZL.js} +1 -1
- package/apps/ui/dist/server/assets/{codex-server-Cqh0hb93.js → codex-server-C01sv0JJ.js} +147 -63
- package/apps/ui/dist/server/assets/{download-CzHmFWGk.js → download-C5rkk_Bo.js} +3 -0
- package/apps/ui/dist/server/assets/formatters-FJaGZgJk.js +91 -0
- package/apps/ui/dist/server/assets/model-label-B1NWGc65.js +13 -0
- package/apps/ui/dist/server/assets/{path-transforms-DD1e7rhY.js → path-transforms-DL2IwtYd.js} +1 -1
- package/apps/ui/dist/server/assets/{projects._project-DdVSdfPe.js → projects._project-CJ7l0ynC.js} +1 -1
- package/apps/ui/dist/server/assets/{projects._project-Bwf6iJC-.js → projects._project-CcJLp_A8.js} +5 -3
- package/apps/ui/dist/server/assets/{projects.index-DKeVeqUZ.js → projects.index-srtogpuF.js} +2 -1
- package/apps/ui/dist/server/assets/{router-ve2Hrl2Y.js → router-C_w-haH6.js} +6 -6
- package/apps/ui/dist/server/assets/{routes-BJyx5OmO.js → routes-BhbxvJE7.js} +1 -1
- package/apps/ui/dist/server/assets/{routes-pkOwjjYc.js → routes-CPe-ppmC.js} +3 -2
- package/apps/ui/dist/server/assets/{start-BAvbjjfs.js → start-HeKLHD9b.js} +1 -1
- package/apps/ui/dist/server/assets/{threads._threadId-D3PYZIwl.js → threads._threadId-Ba7vv6-K.js} +1 -1
- package/apps/ui/dist/server/assets/{threads._threadId-D3xaWM86.js → threads._threadId-euyNckhj.js} +31 -9
- package/apps/ui/dist/server/server.js +15 -15
- package/package.json +7 -1
- package/src/export-chats.ts +3 -4
- package/src/lib/claude-exporter.ts +1 -1
- package/src/lib/codex-browser-db.ts +146 -59
- package/src/lib/codex-browser-export.ts +39 -3
- package/src/lib/codex-exporter-cli.ts +1 -1
- package/src/lib/codex-exporter-db.ts +19 -20
- package/src/lib/codex-exporter-transcript.ts +38 -25
- package/src/lib/interactive-cli.ts +6 -13
- package/src/lib/model-label.ts +24 -0
- package/src/lib/path-transforms.ts +1 -0
- package/src/lib/shared.ts +2 -24
- package/src/lib/sqlite-retry.ts +15 -1
- package/src/spiracha.ts +3 -4
- package/apps/ui/dist/client/assets/projects._project-B7XcpoLt.js +0 -1
- package/apps/ui/dist/client/assets/projects.index-4vfIwLjw.js +0 -1
- package/apps/ui/dist/client/assets/styles-8Wtc8YJw.css +0 -1
- package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-BjsXNYgm.js +0 -99
- package/apps/ui/dist/server/assets/formatters-B6o5pTY9.js +0 -72
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { n as TSS_SERVER_FUNCTION, t as createServerFn } from "../server.js";
|
|
2
|
+
import { t as formatModelLabel$1 } from "./model-label-B1NWGc65.js";
|
|
2
3
|
import { t as isRetryableSqliteError } from "./sqlite-error-LZDrnxdd.js";
|
|
3
|
-
import { t as applyPathTransforms } from "./path-transforms-
|
|
4
|
+
import { t as applyPathTransforms } from "./path-transforms-DL2IwtYd.js";
|
|
4
5
|
import { finished } from "node:stream/promises";
|
|
5
6
|
import { Database } from "bun:sqlite";
|
|
6
7
|
import { mkdir, mkdtemp, readdir, rename, rm, stat } from "node:fs/promises";
|
|
@@ -40,16 +41,7 @@ var cleanInlineTitle = (value) => {
|
|
|
40
41
|
var cleanExtractedText = (text) => {
|
|
41
42
|
return text.replace(/^\s*<\/?image>\s*$/gm, "").replace(/\n{3,}/g, "\n\n");
|
|
42
43
|
};
|
|
43
|
-
var formatModelLabel =
|
|
44
|
-
if (!value) return "Assistant";
|
|
45
|
-
return value.split(/[-_\s]+/u).filter(Boolean).map((part) => {
|
|
46
|
-
const lower = part.toLowerCase();
|
|
47
|
-
if (lower === "gpt") return "GPT";
|
|
48
|
-
if (/^[a-z]\d$/u.test(lower)) return lower.toUpperCase();
|
|
49
|
-
if (/^\d+(\.\d+)*$/u.test(part)) return part;
|
|
50
|
-
return `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`;
|
|
51
|
-
}).join(" ");
|
|
52
|
-
};
|
|
44
|
+
var formatModelLabel = formatModelLabel$1;
|
|
53
45
|
var asObject = (value) => {
|
|
54
46
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
55
47
|
return value;
|
|
@@ -598,18 +590,74 @@ var sleepSync = (delayMs) => {
|
|
|
598
590
|
if (delayMs <= 0) return;
|
|
599
591
|
Atomics.wait(SLEEP_BUFFER, 0, 0, delayMs);
|
|
600
592
|
};
|
|
593
|
+
var toRetryExhaustedError = (attemptCount, error) => {
|
|
594
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
595
|
+
return new Error(`SQLite operation failed after ${attemptCount} attempts: ${message}`, { cause: error });
|
|
596
|
+
};
|
|
597
|
+
var shouldRetrySqliteError = (error, attempt, delaysMs) => {
|
|
598
|
+
return isRetryableSqliteError(error) && attempt < delaysMs.length;
|
|
599
|
+
};
|
|
601
600
|
var runWithSqliteRetry = ({ action, delaysMs = DEFAULT_RETRY_DELAYS_MS, sleep = sleepSync }) => {
|
|
602
601
|
let attempt = 0;
|
|
603
602
|
while (true) try {
|
|
604
603
|
return action();
|
|
605
604
|
} catch (error) {
|
|
606
|
-
if (!
|
|
605
|
+
if (!shouldRetrySqliteError(error, attempt, delaysMs)) {
|
|
606
|
+
if (isRetryableSqliteError(error)) throw toRetryExhaustedError(attempt + 1, error);
|
|
607
|
+
throw error;
|
|
608
|
+
}
|
|
607
609
|
sleep(delaysMs[attempt] ?? 0);
|
|
608
610
|
attempt += 1;
|
|
609
611
|
}
|
|
610
612
|
};
|
|
611
613
|
//#endregion
|
|
612
614
|
//#region ../../src/lib/codex-browser-db.ts
|
|
615
|
+
var SQLITE_DELETE_BATCH_SIZE = 400;
|
|
616
|
+
var SESSION_FILE_DELETE_CONCURRENCY = 16;
|
|
617
|
+
var THREAD_LIST_IO_CONCURRENCY = 8;
|
|
618
|
+
var chunkValues = (values, chunkSize) => {
|
|
619
|
+
const chunks = [];
|
|
620
|
+
for (let index = 0; index < values.length; index += chunkSize) chunks.push(values.slice(index, index + chunkSize));
|
|
621
|
+
return chunks;
|
|
622
|
+
};
|
|
623
|
+
var isPromiseLike = (value) => {
|
|
624
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) return false;
|
|
625
|
+
return "then" in value && typeof value.then === "function";
|
|
626
|
+
};
|
|
627
|
+
var mapWithConcurrency = async (values, limit, mapper) => {
|
|
628
|
+
const results = new Array(values.length);
|
|
629
|
+
let nextIndex = 0;
|
|
630
|
+
const worker = async () => {
|
|
631
|
+
while (true) {
|
|
632
|
+
const currentIndex = nextIndex;
|
|
633
|
+
nextIndex += 1;
|
|
634
|
+
if (currentIndex >= values.length) return;
|
|
635
|
+
results[currentIndex] = await mapper(values[currentIndex], currentIndex);
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
await Promise.all(Array.from({ length: Math.min(limit, values.length) }, () => worker()));
|
|
639
|
+
return results;
|
|
640
|
+
};
|
|
641
|
+
var openReadonlyDb = (dbPath, busyTimeoutMs) => {
|
|
642
|
+
const db = new Database(dbPath, { readonly: true });
|
|
643
|
+
try {
|
|
644
|
+
db.exec(`PRAGMA busy_timeout = ${busyTimeoutMs}`);
|
|
645
|
+
return db;
|
|
646
|
+
} catch (error) {
|
|
647
|
+
db.close();
|
|
648
|
+
throw error;
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
var openWritableDb = (dbPath, busyTimeoutMs) => {
|
|
652
|
+
const db = new Database(dbPath);
|
|
653
|
+
try {
|
|
654
|
+
db.exec(`PRAGMA busy_timeout = ${busyTimeoutMs}`);
|
|
655
|
+
return db;
|
|
656
|
+
} catch (error) {
|
|
657
|
+
db.close();
|
|
658
|
+
throw error;
|
|
659
|
+
}
|
|
660
|
+
};
|
|
613
661
|
var toTimestampMs = (thread) => {
|
|
614
662
|
return thread.updated_at_ms ?? thread.updated_at * 1e3;
|
|
615
663
|
};
|
|
@@ -634,10 +682,11 @@ var parseJsonSafely$1 = (value) => {
|
|
|
634
682
|
};
|
|
635
683
|
var withReadonlyDb = (dbPath, callback) => {
|
|
636
684
|
return runWithSqliteRetry({ action: () => {
|
|
637
|
-
const db =
|
|
638
|
-
db.exec("PRAGMA busy_timeout = 5000");
|
|
685
|
+
const db = openReadonlyDb(dbPath, 5e3);
|
|
639
686
|
try {
|
|
640
|
-
|
|
687
|
+
const result = callback(db);
|
|
688
|
+
if (isPromiseLike(result)) throw new Error("Database callbacks must be synchronous");
|
|
689
|
+
return result;
|
|
641
690
|
} finally {
|
|
642
691
|
db.close();
|
|
643
692
|
}
|
|
@@ -645,12 +694,12 @@ var withReadonlyDb = (dbPath, callback) => {
|
|
|
645
694
|
};
|
|
646
695
|
var withWritableDb = (dbPath, callback) => {
|
|
647
696
|
const db = runWithSqliteRetry({ action: () => {
|
|
648
|
-
|
|
649
|
-
connection.exec("PRAGMA busy_timeout = 5000");
|
|
650
|
-
return connection;
|
|
697
|
+
return openWritableDb(dbPath, 5e3);
|
|
651
698
|
} });
|
|
652
699
|
try {
|
|
653
|
-
|
|
700
|
+
const result = callback(db);
|
|
701
|
+
if (isPromiseLike(result)) throw new Error("Database callbacks must be synchronous");
|
|
702
|
+
return result;
|
|
654
703
|
} finally {
|
|
655
704
|
db.close();
|
|
656
705
|
}
|
|
@@ -665,9 +714,7 @@ var resolveCodexThreadDbPath = () => {
|
|
|
665
714
|
];
|
|
666
715
|
for (const candidate of candidates) try {
|
|
667
716
|
runWithSqliteRetry({ action: () => {
|
|
668
|
-
|
|
669
|
-
connection.exec("PRAGMA busy_timeout = 1500");
|
|
670
|
-
return connection;
|
|
717
|
+
return openReadonlyDb(candidate, 1500);
|
|
671
718
|
} }).close();
|
|
672
719
|
return candidate;
|
|
673
720
|
} catch {}
|
|
@@ -739,8 +786,12 @@ var getExistingTableNames = (db) => {
|
|
|
739
786
|
};
|
|
740
787
|
var getThreadDeleteTargets = (db, threadIds) => {
|
|
741
788
|
if (threadIds.length === 0) return [];
|
|
742
|
-
const
|
|
743
|
-
|
|
789
|
+
const targets = [];
|
|
790
|
+
for (const threadIdChunk of chunkValues(threadIds, SQLITE_DELETE_BATCH_SIZE)) {
|
|
791
|
+
const placeholders = threadIdChunk.map(() => "?").join(", ");
|
|
792
|
+
targets.push(...db.query(`SELECT id, rollout_path FROM threads WHERE id IN (${placeholders})`).all(...threadIdChunk));
|
|
793
|
+
}
|
|
794
|
+
return targets;
|
|
744
795
|
};
|
|
745
796
|
var deleteThreadIds = (db, threadIds) => {
|
|
746
797
|
if (threadIds.length === 0) return {
|
|
@@ -755,12 +806,14 @@ var deleteThreadIds = (db, threadIds) => {
|
|
|
755
806
|
deletedThreadIds: []
|
|
756
807
|
};
|
|
757
808
|
db.transaction((ids) => {
|
|
758
|
-
const
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
809
|
+
for (const threadIdChunk of chunkValues(ids, SQLITE_DELETE_BATCH_SIZE)) {
|
|
810
|
+
const placeholders = threadIdChunk.map(() => "?").join(", ");
|
|
811
|
+
if (existingTableNames.has("thread_dynamic_tools")) db.query(`DELETE FROM thread_dynamic_tools WHERE thread_id IN (${placeholders})`).run(...threadIdChunk);
|
|
812
|
+
if (existingTableNames.has("thread_goals")) db.query(`DELETE FROM thread_goals WHERE thread_id IN (${placeholders})`).run(...threadIdChunk);
|
|
813
|
+
if (existingTableNames.has("stage1_outputs")) db.query(`DELETE FROM stage1_outputs WHERE thread_id IN (${placeholders})`).run(...threadIdChunk);
|
|
814
|
+
if (existingTableNames.has("thread_spawn_edges")) db.query(`DELETE FROM thread_spawn_edges WHERE parent_thread_id IN (${placeholders}) OR child_thread_id IN (${placeholders})`).run(...threadIdChunk, ...threadIdChunk);
|
|
815
|
+
db.query(`DELETE FROM threads WHERE id IN (${placeholders})`).run(...threadIdChunk);
|
|
816
|
+
}
|
|
764
817
|
})(existingIds);
|
|
765
818
|
return {
|
|
766
819
|
deletedSessionFiles: threadTargets.map((target) => target.rollout_path),
|
|
@@ -769,7 +822,10 @@ var deleteThreadIds = (db, threadIds) => {
|
|
|
769
822
|
};
|
|
770
823
|
var deleteThreadSessionFiles = async (sessionFiles) => {
|
|
771
824
|
const uniqueSessionFiles = [...new Set(sessionFiles)];
|
|
772
|
-
await
|
|
825
|
+
await mapWithConcurrency(uniqueSessionFiles, SESSION_FILE_DELETE_CONCURRENCY, async (sessionFile) => {
|
|
826
|
+
await rm(sessionFile, { force: true });
|
|
827
|
+
return sessionFile;
|
|
828
|
+
});
|
|
773
829
|
return uniqueSessionFiles;
|
|
774
830
|
};
|
|
775
831
|
var listCodexProjects = (dbPath) => {
|
|
@@ -783,8 +839,7 @@ var compactThreadListRow = (thread) => {
|
|
|
783
839
|
};
|
|
784
840
|
};
|
|
785
841
|
var listProjectThreads = async (dbPath, projectName, options = {}) => {
|
|
786
|
-
|
|
787
|
-
return (await Promise.all(threads.map(async (thread) => {
|
|
842
|
+
return (await mapWithConcurrency(filterThreadsByProject(readAllThreads(dbPath), projectName), THREAD_LIST_IO_CONCURRENCY, async (thread) => {
|
|
788
843
|
const rollout = await getThreadRolloutLoadState(thread.rollout_path, options.largeTranscriptThresholdBytes);
|
|
789
844
|
if (rollout.shouldDeferTranscriptLoad) return {
|
|
790
845
|
project: projectName,
|
|
@@ -809,7 +864,7 @@ var listProjectThreads = async (dbPath, projectName, options = {}) => {
|
|
|
809
864
|
},
|
|
810
865
|
thread: compactThreadListRow(thread)
|
|
811
866
|
};
|
|
812
|
-
}))
|
|
867
|
+
})).sort((left, right) => toTimestampMs(right.thread) - toTimestampMs(left.thread));
|
|
813
868
|
};
|
|
814
869
|
var getThreadBrowseData = (dbPath, threadId) => {
|
|
815
870
|
return withReadonlyDb(dbPath, (db) => {
|
|
@@ -1005,7 +1060,7 @@ var matchesProjectFilter = (value, projectFilter) => {
|
|
|
1005
1060
|
var convertSessionFile = async (target, options) => {
|
|
1006
1061
|
let transcriptState;
|
|
1007
1062
|
try {
|
|
1008
|
-
transcriptState = await collectCodexTranscript(target.sessionFile, options);
|
|
1063
|
+
transcriptState = await collectCodexTranscript(target.sessionFile, options, target.thread?.model ?? null);
|
|
1009
1064
|
} catch (error) {
|
|
1010
1065
|
const message = error instanceof Error ? error.message : String(error);
|
|
1011
1066
|
throw new Error(`Failed to read Codex transcript ${target.sessionFile}: ${message}`);
|
|
@@ -1024,7 +1079,7 @@ var convertSessionFile = async (target, options) => {
|
|
|
1024
1079
|
};
|
|
1025
1080
|
var writeSessionFileExport = async (target, options, outputPath, transform = (text) => text) => {
|
|
1026
1081
|
const transcriptOutputPath = `${outputPath}.transcript.tmp`;
|
|
1027
|
-
|
|
1082
|
+
let transcriptStream = null;
|
|
1028
1083
|
const state = {
|
|
1029
1084
|
assistantModel: target.thread?.model ?? null,
|
|
1030
1085
|
sections: [],
|
|
@@ -1033,6 +1088,7 @@ var writeSessionFileExport = async (target, options, outputPath, transform = (te
|
|
|
1033
1088
|
};
|
|
1034
1089
|
let wroteSection = false;
|
|
1035
1090
|
try {
|
|
1091
|
+
transcriptStream = await createExportWriteStream(transcriptOutputPath);
|
|
1036
1092
|
for await (const parsed of readJsonlObjects(target.sessionFile)) {
|
|
1037
1093
|
captureSessionMeta(parsed, state.sessionMeta);
|
|
1038
1094
|
const block = renderCodexTranscriptRecord(parsed, options, state);
|
|
@@ -1040,29 +1096,33 @@ var writeSessionFileExport = async (target, options, outputPath, transform = (te
|
|
|
1040
1096
|
transcriptStream.write(transform(wroteSection ? `${getSectionSeparator(options)}${block}` : block));
|
|
1041
1097
|
wroteSection = true;
|
|
1042
1098
|
}
|
|
1099
|
+
await finalizeExportWriteStream(transcriptStream);
|
|
1100
|
+
transcriptStream = null;
|
|
1101
|
+
if (!matchesFilters(target.thread?.cwd ?? state.sessionMeta.cwd ?? null, options) || !wroteSection) return false;
|
|
1102
|
+
const outputStream = await createExportWriteStream(outputPath);
|
|
1103
|
+
try {
|
|
1104
|
+
const prefix = buildStreamExportPrefix(target, state.sessionMeta, options);
|
|
1105
|
+
if (prefix) outputStream.write(transform(prefix));
|
|
1106
|
+
const transcriptReadStream = createReadStream(transcriptOutputPath, { encoding: "utf8" });
|
|
1107
|
+
transcriptReadStream.pipe(outputStream, { end: false });
|
|
1108
|
+
await finished(transcriptReadStream);
|
|
1109
|
+
outputStream.write("\n");
|
|
1110
|
+
await finalizeExportWriteStream(outputStream);
|
|
1111
|
+
} catch (error) {
|
|
1112
|
+
outputStream.destroy();
|
|
1113
|
+
throw error;
|
|
1114
|
+
}
|
|
1115
|
+
return true;
|
|
1043
1116
|
} catch (error) {
|
|
1044
|
-
transcriptStream.destroy();
|
|
1117
|
+
if (transcriptStream) transcriptStream.destroy();
|
|
1045
1118
|
throw error;
|
|
1046
|
-
}
|
|
1047
|
-
await finalizeExportWriteStream(transcriptStream);
|
|
1048
|
-
if (!matchesFilters(target.thread?.cwd ?? state.sessionMeta.cwd ?? null, options) || !wroteSection) {
|
|
1119
|
+
} finally {
|
|
1049
1120
|
await rm(transcriptOutputPath, { force: true });
|
|
1050
|
-
return false;
|
|
1051
1121
|
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
if (prefix) outputStream.write(transform(prefix));
|
|
1055
|
-
const transcriptReadStream = createReadStream(transcriptOutputPath, { encoding: "utf8" });
|
|
1056
|
-
transcriptReadStream.pipe(outputStream, { end: false });
|
|
1057
|
-
await finished(transcriptReadStream);
|
|
1058
|
-
outputStream.write("\n");
|
|
1059
|
-
await finalizeExportWriteStream(outputStream);
|
|
1060
|
-
await rm(transcriptOutputPath, { force: true });
|
|
1061
|
-
return true;
|
|
1062
|
-
};
|
|
1063
|
-
var collectCodexTranscript = async (sessionFile, options) => {
|
|
1122
|
+
};
|
|
1123
|
+
var collectCodexTranscript = async (sessionFile, options, assistantModel = null) => {
|
|
1064
1124
|
const state = {
|
|
1065
|
-
assistantModel
|
|
1125
|
+
assistantModel,
|
|
1066
1126
|
sections: [],
|
|
1067
1127
|
sessionMeta: {},
|
|
1068
1128
|
startedTranscript: false
|
|
@@ -1571,6 +1631,15 @@ var buildBatchExportBaseName = (threads) => {
|
|
|
1571
1631
|
var buildUniqueArchivePath = (exportDir, exportBaseName) => {
|
|
1572
1632
|
return path.join(exportDir, `${exportBaseName}-${randomUUID()}.zip`);
|
|
1573
1633
|
};
|
|
1634
|
+
var buildUniqueBatchEntryBaseName = (baseName, threadId, usedBaseNames) => {
|
|
1635
|
+
if (!usedBaseNames.has(baseName)) {
|
|
1636
|
+
usedBaseNames.add(baseName);
|
|
1637
|
+
return baseName;
|
|
1638
|
+
}
|
|
1639
|
+
const collisionSafeBaseName = `${baseName}-${threadId}`;
|
|
1640
|
+
usedBaseNames.add(collisionSafeBaseName);
|
|
1641
|
+
return collisionSafeBaseName;
|
|
1642
|
+
};
|
|
1574
1643
|
var toDownloadOptions = (input) => {
|
|
1575
1644
|
return {
|
|
1576
1645
|
cwdFilter: null,
|
|
@@ -1623,6 +1692,19 @@ var logRolloutChangeIfDetected = (threadId, rolloutPath, beforeSnapshot, afterSn
|
|
|
1623
1692
|
threadId
|
|
1624
1693
|
});
|
|
1625
1694
|
};
|
|
1695
|
+
var cleanupExportWorkspace = async (workspacePath) => {
|
|
1696
|
+
try {
|
|
1697
|
+
await rm(workspacePath, {
|
|
1698
|
+
force: true,
|
|
1699
|
+
recursive: true
|
|
1700
|
+
});
|
|
1701
|
+
} catch (error) {
|
|
1702
|
+
logExportEvent("warn", "workspace_cleanup_failed", {
|
|
1703
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1704
|
+
workspacePath
|
|
1705
|
+
});
|
|
1706
|
+
}
|
|
1707
|
+
};
|
|
1626
1708
|
var zipExportFile = async (sourcePath, zipPath) => {
|
|
1627
1709
|
const proc = Bun.spawn([
|
|
1628
1710
|
"zip",
|
|
@@ -1695,10 +1777,7 @@ var renderCodexThreadDownload = async (input) => {
|
|
|
1695
1777
|
}, toDownloadOptions(input), savedPath, transform)) throw new Error(`Thread ${input.threadId} produced no exportable content`);
|
|
1696
1778
|
await zipExportFile(savedPath, zipPath);
|
|
1697
1779
|
} finally {
|
|
1698
|
-
await
|
|
1699
|
-
force: true,
|
|
1700
|
-
recursive: true
|
|
1701
|
-
});
|
|
1780
|
+
await cleanupExportWorkspace(workspaceDir);
|
|
1702
1781
|
}
|
|
1703
1782
|
const rolloutSnapshotAfter = await getRolloutSnapshot(browseData.thread.rollout_path);
|
|
1704
1783
|
logRolloutChangeIfDetected(input.threadId, browseData.thread.rollout_path, rolloutSnapshotBefore, rolloutSnapshotAfter);
|
|
@@ -1759,6 +1838,7 @@ var renderCodexThreadsDownload = async (input) => {
|
|
|
1759
1838
|
const exportBaseName = buildBatchExportBaseName(threads);
|
|
1760
1839
|
const bundleDirectory = await createExportWorkspace(exportDir, exportBaseName);
|
|
1761
1840
|
const zipPath = buildUniqueArchivePath(exportDir, exportBaseName);
|
|
1841
|
+
const usedBatchEntryBaseNames = /* @__PURE__ */ new Set();
|
|
1762
1842
|
logExportEvent("info", "batch_start", {
|
|
1763
1843
|
exportBaseName,
|
|
1764
1844
|
selectedThreadCount: threadIds.length,
|
|
@@ -1768,12 +1848,19 @@ var renderCodexThreadsDownload = async (input) => {
|
|
|
1768
1848
|
try {
|
|
1769
1849
|
for (const entry of browseEntries) {
|
|
1770
1850
|
const rolloutSnapshotBefore = await getRolloutSnapshot(entry.thread.rollout_path);
|
|
1771
|
-
const
|
|
1851
|
+
const singleBaseName = buildExportBaseName(entry.thread);
|
|
1852
|
+
const uniqueBaseName = buildUniqueBatchEntryBaseName(singleBaseName, entry.thread.id, usedBatchEntryBaseNames);
|
|
1853
|
+
const relativeFileName = `${uniqueBaseName}.${input.outputFormat === "md" ? "md" : "txt"}`;
|
|
1772
1854
|
const savedPath = path.join(bundleDirectory, relativeFileName);
|
|
1773
1855
|
const transform = (text) => input.pathDisplaySettings ? applyPathTransforms(text, {
|
|
1774
1856
|
...input.pathDisplaySettings,
|
|
1775
1857
|
projectPath: entry.thread.cwd
|
|
1776
1858
|
}) : text;
|
|
1859
|
+
if (uniqueBaseName !== singleBaseName) logExportEvent("warn", "batch_entry_name_collision", {
|
|
1860
|
+
resolvedFileName: relativeFileName,
|
|
1861
|
+
singleBaseName,
|
|
1862
|
+
threadId: entry.thread.id
|
|
1863
|
+
});
|
|
1777
1864
|
if (!await writeSessionFileExport({
|
|
1778
1865
|
fallbackReason: null,
|
|
1779
1866
|
outputRelativePath: relativeFileName,
|
|
@@ -1801,10 +1888,7 @@ var renderCodexThreadsDownload = async (input) => {
|
|
|
1801
1888
|
});
|
|
1802
1889
|
throw error;
|
|
1803
1890
|
} finally {
|
|
1804
|
-
await
|
|
1805
|
-
force: true,
|
|
1806
|
-
recursive: true
|
|
1807
|
-
});
|
|
1891
|
+
await cleanupExportWorkspace(bundleDirectory);
|
|
1808
1892
|
}
|
|
1809
1893
|
const zipStat = await Bun.file(zipPath).stat();
|
|
1810
1894
|
logExportEvent("info", "batch_ready", {
|
|
@@ -124,6 +124,7 @@ function ExportDialog({ open, pending = false, title = "Export thread", onExport
|
|
|
124
124
|
/* @__PURE__ */ jsxs("div", {
|
|
125
125
|
className: "flex items-center gap-3 rounded-2xl border border-[var(--border)] bg-[var(--panel-secondary)] p-3",
|
|
126
126
|
children: [/* @__PURE__ */ jsx(Checkbox$1, {
|
|
127
|
+
"aria-label": "Optimized transcript",
|
|
127
128
|
checked: optimized,
|
|
128
129
|
onCheckedChange: (checked) => setOptimized(checked === true)
|
|
129
130
|
}), /* @__PURE__ */ jsxs("span", {
|
|
@@ -140,6 +141,7 @@ function ExportDialog({ open, pending = false, title = "Export thread", onExport
|
|
|
140
141
|
/* @__PURE__ */ jsxs("div", {
|
|
141
142
|
className: "flex items-center gap-3 rounded-2xl border border-[var(--border)] bg-[var(--panel-secondary)] p-3",
|
|
142
143
|
children: [/* @__PURE__ */ jsx(Checkbox$1, {
|
|
144
|
+
"aria-label": "Include commentary",
|
|
143
145
|
checked: includeCommentary,
|
|
144
146
|
onCheckedChange: (checked) => setIncludeCommentary(checked === true)
|
|
145
147
|
}), /* @__PURE__ */ jsxs("span", {
|
|
@@ -156,6 +158,7 @@ function ExportDialog({ open, pending = false, title = "Export thread", onExport
|
|
|
156
158
|
/* @__PURE__ */ jsxs("div", {
|
|
157
159
|
className: "flex items-center gap-3 rounded-2xl border border-[var(--border)] bg-[var(--panel-secondary)] p-3",
|
|
158
160
|
children: [/* @__PURE__ */ jsx(Checkbox$1, {
|
|
161
|
+
"aria-label": "Include tool calls",
|
|
159
162
|
checked: includeTools,
|
|
160
163
|
onCheckedChange: (checked) => setIncludeTools(checked === true)
|
|
161
164
|
}), /* @__PURE__ */ jsxs("span", {
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { t as formatModelLabel$1 } from "./model-label-B1NWGc65.js";
|
|
2
|
+
//#region src/lib/formatters.ts
|
|
3
|
+
var DATE_TIME_FORMATTERS = /* @__PURE__ */ new Map();
|
|
4
|
+
var getDateTimeFormatters = (timeZone) => {
|
|
5
|
+
const cacheKey = timeZone ?? "local";
|
|
6
|
+
const cached = DATE_TIME_FORMATTERS.get(cacheKey);
|
|
7
|
+
if (cached) return cached;
|
|
8
|
+
const created = {
|
|
9
|
+
dayKeyFormatter: new Intl.DateTimeFormat("en-CA", {
|
|
10
|
+
day: "2-digit",
|
|
11
|
+
month: "2-digit",
|
|
12
|
+
timeZone,
|
|
13
|
+
year: "numeric"
|
|
14
|
+
}),
|
|
15
|
+
timePartsFormatter: new Intl.DateTimeFormat("en-US", {
|
|
16
|
+
day: "numeric",
|
|
17
|
+
hour: "numeric",
|
|
18
|
+
hour12: true,
|
|
19
|
+
minute: "2-digit",
|
|
20
|
+
month: "short",
|
|
21
|
+
timeZone,
|
|
22
|
+
year: "numeric"
|
|
23
|
+
})
|
|
24
|
+
};
|
|
25
|
+
DATE_TIME_FORMATTERS.set(cacheKey, created);
|
|
26
|
+
return created;
|
|
27
|
+
};
|
|
28
|
+
var buildDayKey = (date, timeZone) => {
|
|
29
|
+
return getDateTimeFormatters(timeZone).dayKeyFormatter.format(date);
|
|
30
|
+
};
|
|
31
|
+
var formatTimeParts = (date, timeZone) => {
|
|
32
|
+
const parts = getDateTimeFormatters(timeZone).timePartsFormatter.formatToParts(date);
|
|
33
|
+
const partMap = new Map(parts.map((part) => [part.type, part.value]));
|
|
34
|
+
const hour = partMap.get("hour");
|
|
35
|
+
const minute = partMap.get("minute");
|
|
36
|
+
const dayPeriod = partMap.get("dayPeriod");
|
|
37
|
+
if (!hour || !minute || !dayPeriod) return null;
|
|
38
|
+
return {
|
|
39
|
+
day: partMap.get("day") ?? "",
|
|
40
|
+
month: partMap.get("month") ?? "",
|
|
41
|
+
time: `${hour}:${minute} ${dayPeriod}`.trim(),
|
|
42
|
+
year: partMap.get("year") ?? ""
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
var formatNumber = (value) => {
|
|
46
|
+
return new Intl.NumberFormat("en-US").format(value);
|
|
47
|
+
};
|
|
48
|
+
var formatTokens = (value) => {
|
|
49
|
+
return `${formatNumber(value)} tokens`;
|
|
50
|
+
};
|
|
51
|
+
var formatBytes = (value) => {
|
|
52
|
+
if (!value || value <= 0) return "0 B";
|
|
53
|
+
const units = [
|
|
54
|
+
"B",
|
|
55
|
+
"KB",
|
|
56
|
+
"MB",
|
|
57
|
+
"GB",
|
|
58
|
+
"TB"
|
|
59
|
+
];
|
|
60
|
+
let size = value;
|
|
61
|
+
let unitIndex = 0;
|
|
62
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
63
|
+
size /= 1024;
|
|
64
|
+
unitIndex += 1;
|
|
65
|
+
}
|
|
66
|
+
const fractionDigits = size >= 100 || unitIndex === 0 ? 0 : 1;
|
|
67
|
+
return `${size.toFixed(fractionDigits)} ${units[unitIndex]}`;
|
|
68
|
+
};
|
|
69
|
+
var formatDateTime = (value, options = {}) => {
|
|
70
|
+
if (value === null || value === void 0 || value === "") return "n/a";
|
|
71
|
+
const date = new Date(value);
|
|
72
|
+
if (Number.isNaN(date.getTime())) return "n/a";
|
|
73
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
74
|
+
const parts = formatTimeParts(date, options.timeZone);
|
|
75
|
+
if (!parts) return "n/a";
|
|
76
|
+
const { day, month, time, year } = parts;
|
|
77
|
+
if (buildDayKey(date, options.timeZone) === buildDayKey(now, options.timeZone)) return time;
|
|
78
|
+
const currentYear = formatTimeParts(now, options.timeZone)?.year;
|
|
79
|
+
if (year && currentYear && year !== currentYear) return `${month} ${day}, ${year} · ${time}`;
|
|
80
|
+
return `${month} ${day} · ${time}`;
|
|
81
|
+
};
|
|
82
|
+
var formatList = (values) => {
|
|
83
|
+
if (values.length === 0) return "n/a";
|
|
84
|
+
return values.join(", ");
|
|
85
|
+
};
|
|
86
|
+
var formatBooleanLabel = (value) => {
|
|
87
|
+
return value ? "Yes" : "No";
|
|
88
|
+
};
|
|
89
|
+
var formatModelLabel = formatModelLabel$1;
|
|
90
|
+
//#endregion
|
|
91
|
+
export { formatModelLabel as a, formatList as i, formatBytes as n, formatNumber as o, formatDateTime as r, formatTokens as s, formatBooleanLabel as t };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region ../../src/lib/model-label.ts
|
|
2
|
+
var formatModelLabel = (value) => {
|
|
3
|
+
if (!value) return "Assistant";
|
|
4
|
+
return value.split(/[-_\s]+/u).filter(Boolean).map((part) => {
|
|
5
|
+
const lower = part.toLowerCase();
|
|
6
|
+
if (lower === "gpt") return "GPT";
|
|
7
|
+
if (/^[a-z]\d$/u.test(lower)) return lower.toUpperCase();
|
|
8
|
+
if (/^\d+(\.\d+)*$/u.test(part)) return part;
|
|
9
|
+
return `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`;
|
|
10
|
+
}).join(" ");
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { formatModelLabel as t };
|
package/apps/ui/dist/server/assets/{path-transforms-DD1e7rhY.js → path-transforms-DL2IwtYd.js}
RENAMED
|
@@ -19,7 +19,7 @@ var replaceExactProjectPath = (text, projectPath) => {
|
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
21
|
var redactRemainingUsernames = (text) => {
|
|
22
|
-
return text.replace(/\/Users\/[^/\\]+(?=\/|$)/gu, "~").replace(/[A-Za-z]:[\\/]+Users[\\/]+[^\\/]+(?=[\\/]|$)/gu, "~");
|
|
22
|
+
return text.replace(/\/home\/[^/\\]+(?=\/|$)/gu, "~").replace(/\/Users\/[^/\\]+(?=\/|$)/gu, "~").replace(/[A-Za-z]:[\\/]+Users[\\/]+[^\\/]+(?=[\\/]|$)/gu, "~");
|
|
23
23
|
};
|
|
24
24
|
var applyPathTransforms = (text, settings) => {
|
|
25
25
|
let result = text;
|
package/apps/ui/dist/server/assets/{projects._project-DdVSdfPe.js → projects._project-CJ7l0ynC.js}
RENAMED
|
@@ -4,7 +4,7 @@ import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
|
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
//#region src/routes/projects.$project.tsx
|
|
6
6
|
var $$splitErrorComponentImporter = () => import("./projects._project-CLSohrBp.js");
|
|
7
|
-
var $$splitComponentImporter = () => import("./projects._project-
|
|
7
|
+
var $$splitComponentImporter = () => import("./projects._project-CcJLp_A8.js");
|
|
8
8
|
var Route = createFileRoute("/projects/$project")({
|
|
9
9
|
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
10
10
|
errorComponent: lazyRouteComponent($$splitErrorComponentImporter, "errorComponent"),
|
package/apps/ui/dist/server/assets/{projects._project-Bwf6iJC-.js → projects._project-CcJLp_A8.js}
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { t as Button } from "./button-CmTDnzOn.js";
|
|
2
2
|
import { n as useSettings } from "./settings-store-DpEJEQ7M.js";
|
|
3
3
|
import { c as deleteThreadFn, d as exportThreadsFn, l as deleteThreadsFn, r as projectThreadsQueryOptions, u as exportThreadFn } from "./codex-queries-CAF6HYiG.js";
|
|
4
|
-
import { t as Route } from "./projects._project-
|
|
4
|
+
import { t as Route } from "./projects._project-CJ7l0ynC.js";
|
|
5
5
|
import { t as DataTable } from "./data-table-Cdct823O.js";
|
|
6
6
|
import { t as PageHeader } from "./page-header-CxdZM86z.js";
|
|
7
|
-
import { n as formatBytes, o as formatNumber, r as formatDateTime, s as formatTokens } from "./formatters-
|
|
7
|
+
import { n as formatBytes, o as formatNumber, r as formatDateTime, s as formatTokens } from "./formatters-FJaGZgJk.js";
|
|
8
8
|
import { t as DeleteConfirmDialog } from "./delete-confirm-dialog-CWqcTXTF.js";
|
|
9
|
-
import { n as downloadUrlFile, r as ExportDialog, t as downloadTextFile } from "./download-
|
|
9
|
+
import { n as downloadUrlFile, r as ExportDialog, t as downloadTextFile } from "./download-C5rkk_Bo.js";
|
|
10
10
|
import { a as DropdownMenuTrigger, i as DropdownMenuItem, n as DropdownMenu, r as DropdownMenuContent, t as Input } from "./input-B4tEzctc.js";
|
|
11
11
|
import { startTransition, useDeferredValue, useState } from "react";
|
|
12
12
|
import { Link } from "@tanstack/react-router";
|
|
@@ -40,6 +40,7 @@ var columns = (onDeleteThread, onExportThread) => [
|
|
|
40
40
|
columnHelper.accessor((row) => row.thread.updated_at_ms ?? row.thread.updated_at * 1e3, {
|
|
41
41
|
cell: (info) => /* @__PURE__ */ jsx("span", {
|
|
42
42
|
className: "whitespace-nowrap text-sm",
|
|
43
|
+
suppressHydrationWarning: true,
|
|
43
44
|
children: formatDateTime(info.getValue())
|
|
44
45
|
}),
|
|
45
46
|
header: "Updated",
|
|
@@ -48,6 +49,7 @@ var columns = (onDeleteThread, onExportThread) => [
|
|
|
48
49
|
columnHelper.accessor((row) => row.thread.created_at_ms ?? row.thread.created_at * 1e3, {
|
|
49
50
|
cell: (info) => /* @__PURE__ */ jsx("span", {
|
|
50
51
|
className: "whitespace-nowrap text-sm",
|
|
52
|
+
suppressHydrationWarning: true,
|
|
51
53
|
children: formatDateTime(info.getValue())
|
|
52
54
|
}),
|
|
53
55
|
header: "Created",
|
package/apps/ui/dist/server/assets/{projects.index-DKeVeqUZ.js → projects.index-srtogpuF.js}
RENAMED
|
@@ -2,7 +2,7 @@ import { t as Button } from "./button-CmTDnzOn.js";
|
|
|
2
2
|
import { i as projectsQueryOptions, s as deleteProjectFn } from "./codex-queries-CAF6HYiG.js";
|
|
3
3
|
import { t as DataTable } from "./data-table-Cdct823O.js";
|
|
4
4
|
import { t as PageHeader } from "./page-header-CxdZM86z.js";
|
|
5
|
-
import { i as formatList, o as formatNumber, r as formatDateTime, s as formatTokens } from "./formatters-
|
|
5
|
+
import { i as formatList, o as formatNumber, r as formatDateTime, s as formatTokens } from "./formatters-FJaGZgJk.js";
|
|
6
6
|
import { t as DeleteConfirmDialog } from "./delete-confirm-dialog-CWqcTXTF.js";
|
|
7
7
|
import { a as DropdownMenuTrigger, i as DropdownMenuItem, n as DropdownMenu, r as DropdownMenuContent, t as Input } from "./input-B4tEzctc.js";
|
|
8
8
|
import { startTransition, useDeferredValue, useState } from "react";
|
|
@@ -48,6 +48,7 @@ var columns = (onDeleteProject) => [
|
|
|
48
48
|
columnHelper.accessor("lastUpdatedAtMs", {
|
|
49
49
|
cell: (info) => /* @__PURE__ */ jsx("span", {
|
|
50
50
|
className: "text-sm",
|
|
51
|
+
suppressHydrationWarning: true,
|
|
51
52
|
children: formatDateTime(info.getValue())
|
|
52
53
|
}),
|
|
53
54
|
header: "Last updated"
|
|
@@ -2,9 +2,9 @@ import { t as cn } from "./utils-C_uf36nf.js";
|
|
|
2
2
|
import { t as Button } from "./button-CmTDnzOn.js";
|
|
3
3
|
import { t as SettingsProvider } from "./settings-store-DpEJEQ7M.js";
|
|
4
4
|
import { i as projectsQueryOptions, t as analyticsQueryOptions } from "./codex-queries-CAF6HYiG.js";
|
|
5
|
-
import { t as Route$5 } from "./routes-
|
|
6
|
-
import { t as Route$6 } from "./threads._threadId-
|
|
7
|
-
import { t as Route$7 } from "./projects._project-
|
|
5
|
+
import { t as Route$5 } from "./routes-BhbxvJE7.js";
|
|
6
|
+
import { t as Route$6 } from "./threads._threadId-Ba7vv6-K.js";
|
|
7
|
+
import { t as Route$7 } from "./projects._project-CJ7l0ynC.js";
|
|
8
8
|
import { useEffect, useState } from "react";
|
|
9
9
|
import { HeadContent, Link, Outlet, Scripts, createFileRoute, createRootRouteWithContext, createRouter, lazyRouteComponent, notFound, redirect, useRouterState } from "@tanstack/react-router";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -124,7 +124,7 @@ function TooltipProvider({ delayDuration = 0, ...props }) {
|
|
|
124
124
|
}
|
|
125
125
|
//#endregion
|
|
126
126
|
//#region src/styles.css?url
|
|
127
|
-
var styles_default = "/assets/styles-
|
|
127
|
+
var styles_default = "/assets/styles-CMrP9Jb4.css";
|
|
128
128
|
//#endregion
|
|
129
129
|
//#region src/routes/__root.tsx
|
|
130
130
|
var themeInitScript = `
|
|
@@ -207,7 +207,7 @@ var $$splitComponentImporter$3 = () => import("./settings-MvWDgc1u.js");
|
|
|
207
207
|
var Route$3 = createFileRoute("/settings")({ component: lazyRouteComponent($$splitComponentImporter$3, "component") });
|
|
208
208
|
//#endregion
|
|
209
209
|
//#region src/routes/analytics.tsx
|
|
210
|
-
var $$splitComponentImporter$2 = () => import("./analytics-
|
|
210
|
+
var $$splitComponentImporter$2 = () => import("./analytics-BMxW_bZL.js");
|
|
211
211
|
var Route$2 = createFileRoute("/analytics")({
|
|
212
212
|
component: lazyRouteComponent($$splitComponentImporter$2, "component"),
|
|
213
213
|
loader: ({ context }) => {
|
|
@@ -234,7 +234,7 @@ var Route$1 = createFileRoute("/$threadId")({
|
|
|
234
234
|
//#endregion
|
|
235
235
|
//#region src/routes/projects.index.tsx
|
|
236
236
|
var $$splitErrorComponentImporter = () => import("./projects.index-CaplpeMy.js");
|
|
237
|
-
var $$splitComponentImporter = () => import("./projects.index-
|
|
237
|
+
var $$splitComponentImporter = () => import("./projects.index-srtogpuF.js");
|
|
238
238
|
var Route = createFileRoute("/projects/")({
|
|
239
239
|
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
240
240
|
errorComponent: lazyRouteComponent($$splitErrorComponentImporter, "errorComponent"),
|
|
@@ -2,7 +2,7 @@ import { n as dashboardQueryOptions } from "./codex-queries-CAF6HYiG.js";
|
|
|
2
2
|
import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
//#region src/routes/index.tsx
|
|
5
|
-
var $$splitComponentImporter = () => import("./routes-
|
|
5
|
+
var $$splitComponentImporter = () => import("./routes-CPe-ppmC.js");
|
|
6
6
|
var Route = createFileRoute("/")({
|
|
7
7
|
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
8
8
|
loader: ({ context }) => context.queryClient.ensureQueryData(dashboardQueryOptions())
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as dashboardQueryOptions } from "./codex-queries-CAF6HYiG.js";
|
|
2
|
-
import { t as Route } from "./routes-
|
|
2
|
+
import { t as Route } from "./routes-BhbxvJE7.js";
|
|
3
3
|
import { t as MetricCard } from "./metric-card-ByEeLu0r.js";
|
|
4
4
|
import { t as PageHeader } from "./page-header-CxdZM86z.js";
|
|
5
|
-
import { o as formatNumber, r as formatDateTime, s as formatTokens } from "./formatters-
|
|
5
|
+
import { o as formatNumber, r as formatDateTime, s as formatTokens } from "./formatters-FJaGZgJk.js";
|
|
6
6
|
import { Link } from "@tanstack/react-router";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
@@ -101,6 +101,7 @@ function DashboardPage() {
|
|
|
101
101
|
})]
|
|
102
102
|
}), /* @__PURE__ */ jsx("p", {
|
|
103
103
|
className: "shrink-0 whitespace-nowrap font-mono text-[var(--muted-foreground)] text-xs",
|
|
104
|
+
suppressHydrationWarning: true,
|
|
104
105
|
children: formatDateTime(thread.updated_at_ms ?? thread.updated_at * 1e3)
|
|
105
106
|
})]
|
|
106
107
|
}), /* @__PURE__ */ jsxs("div", {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region ../../node_modules/.bun/@tanstack+react-start@1.168.11+
|
|
1
|
+
//#region ../../node_modules/.bun/@tanstack+react-start@1.168.11+5cefe02f681c7619/node_modules/@tanstack/react-start/dist/plugin/default-entry/start.ts
|
|
2
2
|
var startInstance = void 0;
|
|
3
3
|
//#endregion
|
|
4
4
|
export { startInstance };
|