spiracha 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +13 -7
- package/README.md +6 -2
- package/apps/ui/AGENTS.md +2 -0
- package/apps/ui/README.md +3 -1
- package/apps/ui/dist/client/assets/{analytics-CqWZmyV6.js → analytics-Cv0JMDN2.js} +1 -1
- package/apps/ui/dist/client/assets/{checkbox-DXM4lkJq.js → checkbox-DjHij7DJ.js} +1 -1
- package/apps/ui/dist/client/assets/{data-table-DnPYMPCD.js → data-table-Bgnh7phF.js} +1 -1
- package/apps/ui/dist/client/assets/{delete-confirm-dialog-CcZaRX33.js → delete-confirm-dialog-CIZy_LXD.js} +1 -1
- package/apps/ui/dist/client/assets/download-DQtfva4z.js +1 -0
- package/apps/ui/dist/client/assets/{es2015-Bm0kEzx2.js → es2015-DsDKdYCE.js} +1 -1
- package/apps/ui/dist/client/assets/{formatters-C12LmYaa.js → formatters-CWFrMKSn.js} +1 -1
- package/apps/ui/dist/client/assets/{index-DdJ7ahIt.js → index-C_-e0lDI.js} +2 -2
- package/apps/ui/dist/client/assets/{input-CEsI7EpI.js → input-BbgApiqZ.js} +1 -1
- package/apps/ui/dist/client/assets/{metric-card-9jwBF7rG.js → metric-card-BJX5rkHK.js} +1 -1
- package/apps/ui/dist/client/assets/{page-header-Dr_h1CVv.js → page-header-ODLuGLAB.js} +1 -1
- package/apps/ui/dist/client/assets/{projects._project-uyNGnpjH.js → projects._project-C2Pys_bB.js} +1 -1
- package/apps/ui/dist/client/assets/{projects._project-zoM8d2nH.js → projects._project-CHvAKvlu.js} +1 -1
- package/apps/ui/dist/client/assets/{projects.index-D1CWVN-O.js → projects.index-BmwtS1x-.js} +1 -1
- package/apps/ui/dist/client/assets/{projects.index-DukMuny6.js → projects.index-CuLw73mt.js} +1 -1
- package/apps/ui/dist/client/assets/{routes-Gr2Wwh83.js → routes-CfnaTOlj.js} +1 -1
- package/apps/ui/dist/client/assets/{select-CFim44gT.js → select-B1kH_5lx.js} +1 -1
- package/apps/ui/dist/client/assets/{settings-DqhyDxo2.js → settings-mYTB3sso.js} +1 -1
- package/apps/ui/dist/client/assets/{threads._threadId-DT75NiBa.js → threads._threadId-CUiCZSwo.js} +1 -1
- package/apps/ui/dist/client/assets/{threads._threadId-Df5VXIuZ.js → threads._threadId-C_47okme.js} +1 -1
- package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-kj_QB_26.js +99 -0
- package/apps/ui/dist/server/assets/{analytics-BMxW_bZL.js → analytics-2QpLKjlG.js} +1 -1
- package/apps/ui/dist/server/assets/{codex-queries-CAF6HYiG.js → codex-queries-BH4Cb0v3.js} +2 -2
- package/apps/ui/dist/server/assets/{codex-server-BFZq2Y2O.js → codex-server-DqzruLmg.js} +35 -87
- package/apps/ui/dist/server/assets/{download-C5rkk_Bo.js → download-Drctxary.js} +7 -7
- package/apps/ui/dist/server/assets/{projects._project-CcJLp_A8.js → projects._project-DreIU5b0.js} +3 -3
- package/apps/ui/dist/server/assets/{projects._project-CJ7l0ynC.js → projects._project-gT01HBqH.js} +2 -2
- package/apps/ui/dist/server/assets/{projects.index-srtogpuF.js → projects.index-BYmgSGAj.js} +1 -1
- package/apps/ui/dist/server/assets/{router-C_w-haH6.js → router-Qj5Kn7bl.js} +6 -6
- package/apps/ui/dist/server/assets/{routes-BhbxvJE7.js → routes-BtcXuK0x.js} +2 -2
- package/apps/ui/dist/server/assets/{routes-CPe-ppmC.js → routes-_LbCIjtJ.js} +2 -2
- package/apps/ui/dist/server/assets/{threads._threadId-euyNckhj.js → threads._threadId-D5m6ypGw.js} +3 -3
- package/apps/ui/dist/server/assets/{threads._threadId-Ba7vv6-K.js → threads._threadId-DcbAJkwf.js} +2 -2
- package/apps/ui/dist/server/server.js +19 -36
- package/bin/codex-chats-claude.js +5 -0
- package/bin/codex-chats.js +5 -0
- package/bin/spiracha.js +5 -0
- package/package.json +9 -6
- package/src/lib/codex-browser-export.ts +28 -3
- package/src/lib/codex-exporter-cli.ts +9 -9
- package/src/lib/codex-exporter-transcript.ts +16 -190
- package/src/lib/codex-exporter-types.ts +1 -1
- package/src/lib/codex-exporter.ts +0 -1
- package/src/lib/interactive-cli.ts +2 -2
- package/src/mcp-server.ts +2 -2
- package/apps/ui/dist/client/assets/download-DOwxk-cG.js +0 -1
- package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-C0V305Nt.js +0 -99
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
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
|
-
import { i as projectsQueryOptions, t as analyticsQueryOptions } from "./codex-queries-
|
|
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-
|
|
4
|
+
import { i as projectsQueryOptions, t as analyticsQueryOptions } from "./codex-queries-BH4Cb0v3.js";
|
|
5
|
+
import { t as Route$5 } from "./routes-BtcXuK0x.js";
|
|
6
|
+
import { t as Route$6 } from "./threads._threadId-DcbAJkwf.js";
|
|
7
|
+
import { t as Route$7 } from "./projects._project-gT01HBqH.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";
|
|
@@ -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-2QpLKjlG.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-BYmgSGAj.js");
|
|
238
238
|
var Route = createFileRoute("/projects/")({
|
|
239
239
|
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
240
240
|
errorComponent: lazyRouteComponent($$splitErrorComponentImporter, "errorComponent"),
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { n as dashboardQueryOptions } from "./codex-queries-
|
|
1
|
+
import { n as dashboardQueryOptions } from "./codex-queries-BH4Cb0v3.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-_LbCIjtJ.js");
|
|
6
6
|
var Route = createFileRoute("/")({
|
|
7
7
|
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
8
8
|
loader: ({ context }) => context.queryClient.ensureQueryData(dashboardQueryOptions())
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as dashboardQueryOptions } from "./codex-queries-
|
|
2
|
-
import { t as Route } from "./routes-
|
|
1
|
+
import { n as dashboardQueryOptions } from "./codex-queries-BH4Cb0v3.js";
|
|
2
|
+
import { t as Route } from "./routes-BtcXuK0x.js";
|
|
3
3
|
import { t as MetricCard } from "./metric-card-ByEeLu0r.js";
|
|
4
4
|
import { t as PageHeader } from "./page-header-CxdZM86z.js";
|
|
5
5
|
import { o as formatNumber, r as formatDateTime, s as formatTokens } from "./formatters-FJaGZgJk.js";
|
package/apps/ui/dist/server/assets/{threads._threadId-euyNckhj.js → threads._threadId-D5m6ypGw.js}
RENAMED
|
@@ -2,14 +2,14 @@ import { t as applyPathTransforms$1 } from "./path-transforms-DL2IwtYd.js";
|
|
|
2
2
|
import { t as cn } from "./utils-C_uf36nf.js";
|
|
3
3
|
import { t as Button } from "./button-CmTDnzOn.js";
|
|
4
4
|
import { n as useSettings } from "./settings-store-DpEJEQ7M.js";
|
|
5
|
-
import { a as threadSnapshotQueryOptions, c as deleteThreadFn, o as threadTranscriptQueryOptions, u as exportThreadFn } from "./codex-queries-
|
|
6
|
-
import { t as Route } from "./threads._threadId-
|
|
5
|
+
import { a as threadSnapshotQueryOptions, c as deleteThreadFn, o as threadTranscriptQueryOptions, u as exportThreadFn } from "./codex-queries-BH4Cb0v3.js";
|
|
6
|
+
import { t as Route } from "./threads._threadId-DcbAJkwf.js";
|
|
7
7
|
import { t as Checkbox$1 } from "./checkbox-C0hovF41.js";
|
|
8
8
|
import { t as MetricCard } from "./metric-card-ByEeLu0r.js";
|
|
9
9
|
import { t as PageHeader } from "./page-header-CxdZM86z.js";
|
|
10
10
|
import { a as formatModelLabel, i as formatList, n as formatBytes, r as formatDateTime, s as formatTokens, t as formatBooleanLabel } from "./formatters-FJaGZgJk.js";
|
|
11
11
|
import { t as DeleteConfirmDialog } from "./delete-confirm-dialog-CWqcTXTF.js";
|
|
12
|
-
import { n as downloadUrlFile, r as ExportDialog, t as downloadTextFile } from "./download-
|
|
12
|
+
import { n as downloadUrlFile, r as ExportDialog, t as downloadTextFile } from "./download-Drctxary.js";
|
|
13
13
|
import { useEffect, useRef, useState } from "react";
|
|
14
14
|
import { Link, useNavigate } from "@tanstack/react-router";
|
|
15
15
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
package/apps/ui/dist/server/assets/{threads._threadId-Ba7vv6-K.js → threads._threadId-DcbAJkwf.js}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as threadSnapshotQueryOptions } from "./codex-queries-
|
|
1
|
+
import { a as threadSnapshotQueryOptions } from "./codex-queries-BH4Cb0v3.js";
|
|
2
2
|
import { t as LoadingPanel } from "./loading-panel-DbLdvjtR.js";
|
|
3
3
|
import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
//#region src/routes/threads.$threadId.tsx
|
|
6
6
|
var $$splitErrorComponentImporter = () => import("./threads._threadId-BSSK4nkI.js");
|
|
7
|
-
var $$splitComponentImporter = () => import("./threads._threadId-
|
|
7
|
+
var $$splitComponentImporter = () => import("./threads._threadId-D5m6ypGw.js");
|
|
8
8
|
var Route = createFileRoute("/threads/$threadId")({
|
|
9
9
|
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
10
10
|
errorComponent: lazyRouteComponent($$splitErrorComponentImporter, "errorComponent"),
|
|
@@ -23,7 +23,7 @@ var NullProtoObj = /* @__PURE__ */ (() => {
|
|
|
23
23
|
return e.prototype = Object.create(null), Object.freeze(e.prototype), e;
|
|
24
24
|
})();
|
|
25
25
|
//#endregion
|
|
26
|
-
//#region ../../node_modules/.bun/srvx@0.11.
|
|
26
|
+
//#region ../../node_modules/.bun/srvx@0.11.16/node_modules/srvx/dist/_chunks/_url.mjs
|
|
27
27
|
function lazyInherit(target, source, sourceKey) {
|
|
28
28
|
for (const key of [...Object.getOwnPropertyNames(source), ...Object.getOwnPropertySymbols(source)]) {
|
|
29
29
|
if (key === "constructor") continue;
|
|
@@ -52,20 +52,6 @@ function lazyInherit(target, source, sourceKey) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
var _needsNormRE = /(?:(?:^|\/)(?:\.|\.\.|%2e|%2e\.|\.%2e|%2e%2e)(?:\/|$))|[\\^\x80-\uffff]/i;
|
|
55
|
-
/**
|
|
56
|
-
* URL wrapper with fast paths to access to the following props:
|
|
57
|
-
*
|
|
58
|
-
* - `url.pathname`
|
|
59
|
-
* - `url.search`
|
|
60
|
-
* - `url.searchParams`
|
|
61
|
-
* - `url.protocol`
|
|
62
|
-
*
|
|
63
|
-
* **NOTES:**
|
|
64
|
-
*
|
|
65
|
-
* - It is assumed that the input URL is **already encoded** and formatted from an HTTP request and contains no hash.
|
|
66
|
-
* - Triggering the setters or getters on other props will deoptimize to full URL parsing.
|
|
67
|
-
* - Changes to `searchParams` will be discarded as we don't track them.
|
|
68
|
-
*/
|
|
69
55
|
var FastURL = /* @__PURE__ */ (() => {
|
|
70
56
|
const NativeURL = globalThis.URL;
|
|
71
57
|
const FastURL = class URL {
|
|
@@ -113,10 +99,11 @@ var FastURL = /* @__PURE__ */ (() => {
|
|
|
113
99
|
const url = this.href;
|
|
114
100
|
const protoIndex = url.indexOf("://");
|
|
115
101
|
const pathnameIndex = protoIndex === -1 ? -1 : url.indexOf("/", protoIndex + 4);
|
|
102
|
+
const qIndex = pathnameIndex === -1 ? -1 : url.indexOf("?", pathnameIndex);
|
|
116
103
|
this.#pos = [
|
|
117
104
|
protoIndex,
|
|
118
105
|
pathnameIndex,
|
|
119
|
-
|
|
106
|
+
qIndex
|
|
120
107
|
];
|
|
121
108
|
}
|
|
122
109
|
return this.#pos;
|
|
@@ -150,7 +137,8 @@ var FastURL = /* @__PURE__ */ (() => {
|
|
|
150
137
|
if (this.#protocol === void 0) {
|
|
151
138
|
const [protocolIndex] = this.#getPos();
|
|
152
139
|
if (protocolIndex === -1) return this._url.protocol;
|
|
153
|
-
|
|
140
|
+
const url = this.href;
|
|
141
|
+
this.#protocol = url.slice(0, protocolIndex + 1);
|
|
154
142
|
}
|
|
155
143
|
return this.#protocol;
|
|
156
144
|
}
|
|
@@ -167,12 +155,7 @@ var FastURL = /* @__PURE__ */ (() => {
|
|
|
167
155
|
return FastURL;
|
|
168
156
|
})();
|
|
169
157
|
//#endregion
|
|
170
|
-
//#region ../../node_modules/.bun/srvx@0.11.
|
|
171
|
-
/**
|
|
172
|
-
* Fast Response for Node.js runtime
|
|
173
|
-
*
|
|
174
|
-
* It is faster because in most cases it doesn't create a full Response instance.
|
|
175
|
-
*/
|
|
158
|
+
//#region ../../node_modules/.bun/srvx@0.11.16/node_modules/srvx/dist/adapters/node.mjs
|
|
176
159
|
var NodeResponse = /* @__PURE__ */ (() => {
|
|
177
160
|
const NativeResponse = globalThis.Response;
|
|
178
161
|
const STATUS_CODES = globalThis.process?.getBuiltinModule?.("node:http")?.STATUS_CODES || {};
|
|
@@ -3471,7 +3454,7 @@ var defaultSerovalPlugins = [
|
|
|
3471
3454
|
* the dev styles URL for route-scoped CSS collection.
|
|
3472
3455
|
*/
|
|
3473
3456
|
async function getStartManifest(matchedRoutes) {
|
|
3474
|
-
const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-
|
|
3457
|
+
const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-kj_QB_26.js");
|
|
3475
3458
|
const startManifest = tsrStartManifest();
|
|
3476
3459
|
let routes = startManifest.routes;
|
|
3477
3460
|
routes[rootRouteId];
|
|
@@ -3498,47 +3481,47 @@ async function getStartManifest(matchedRoutes) {
|
|
|
3498
3481
|
var manifest = {
|
|
3499
3482
|
"0814663c3bdc58135f97d210d145ef0be5ca54ef9a5f1e3030be9b1bfc901e30": {
|
|
3500
3483
|
functionName: "exportThreadFn_createServerFn_handler",
|
|
3501
|
-
importer: () => import("./assets/codex-server-
|
|
3484
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3502
3485
|
},
|
|
3503
3486
|
"164ee82cdd565ed96591a64312f0f7bd961040baf066a89d9f5636330d11360b": {
|
|
3504
3487
|
functionName: "deleteProjectFn_createServerFn_handler",
|
|
3505
|
-
importer: () => import("./assets/codex-server-
|
|
3488
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3506
3489
|
},
|
|
3507
3490
|
"29727b7ad5b8fe42e83817376653e064d9fe8888799f056b2e59296b3396568b": {
|
|
3508
3491
|
functionName: "deleteThreadFn_createServerFn_handler",
|
|
3509
|
-
importer: () => import("./assets/codex-server-
|
|
3492
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3510
3493
|
},
|
|
3511
3494
|
"4712520da0f07bbd1f0907e5a162fe518516ff4caca3fd23876cc65539d87d7a": {
|
|
3512
3495
|
functionName: "getAnalyticsFn_createServerFn_handler",
|
|
3513
|
-
importer: () => import("./assets/codex-server-
|
|
3496
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3514
3497
|
},
|
|
3515
3498
|
"59fb2cb4d60c8e7d47e0afcc914ee6f9d9f4bf076c8e66eab1693066753655b3": {
|
|
3516
3499
|
functionName: "listProjectThreadsFn_createServerFn_handler",
|
|
3517
|
-
importer: () => import("./assets/codex-server-
|
|
3500
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3518
3501
|
},
|
|
3519
3502
|
"5da27045f7e28ded6353bc16aace284af7ef1b4010ef04d0186a6feadb466497": {
|
|
3520
3503
|
functionName: "getThreadTranscriptFn_createServerFn_handler",
|
|
3521
|
-
importer: () => import("./assets/codex-server-
|
|
3504
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3522
3505
|
},
|
|
3523
3506
|
"72991e2b6e0adbf8d63bb8b139dad88a00b77b7030ec28ceac36c3cce7846b4c": {
|
|
3524
3507
|
functionName: "getThreadSnapshotFn_createServerFn_handler",
|
|
3525
|
-
importer: () => import("./assets/codex-server-
|
|
3508
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3526
3509
|
},
|
|
3527
3510
|
"792690638a3b10035a5b7368c3d98bdc70cbfe1e36a4aa5f45b1c49b8b1025b0": {
|
|
3528
3511
|
functionName: "getDashboardSummaryFn_createServerFn_handler",
|
|
3529
|
-
importer: () => import("./assets/codex-server-
|
|
3512
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3530
3513
|
},
|
|
3531
3514
|
"96aa60bf7dd9b5bde415bcf3ad6f6955a975eecd9aa0516cf401cc39bebebe6c": {
|
|
3532
3515
|
functionName: "deleteThreadsFn_createServerFn_handler",
|
|
3533
|
-
importer: () => import("./assets/codex-server-
|
|
3516
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3534
3517
|
},
|
|
3535
3518
|
"b4e15c006e9a277470958bb008f89b5b0acc7256109581de44cf17d587d174a5": {
|
|
3536
3519
|
functionName: "exportThreadsFn_createServerFn_handler",
|
|
3537
|
-
importer: () => import("./assets/codex-server-
|
|
3520
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3538
3521
|
},
|
|
3539
3522
|
"ccefccb816ba13508f23db4e31067b3403e750225257592d3ae11071ffc3fd6f": {
|
|
3540
3523
|
functionName: "listProjectsFn_createServerFn_handler",
|
|
3541
|
-
importer: () => import("./assets/codex-server-
|
|
3524
|
+
importer: () => import("./assets/codex-server-DqzruLmg.js")
|
|
3542
3525
|
}
|
|
3543
3526
|
};
|
|
3544
3527
|
async function getServerFnById(id, access) {
|
|
@@ -5328,7 +5311,7 @@ var getBaseManifest = getProdBaseManifest;
|
|
|
5328
5311
|
var createEarlyHintsForRequest = createEarlyHintsCollector;
|
|
5329
5312
|
async function loadEntries() {
|
|
5330
5313
|
const [routerEntry, startEntry, pluginAdapters] = await Promise.all([
|
|
5331
|
-
import("./assets/router-
|
|
5314
|
+
import("./assets/router-Qj5Kn7bl.js"),
|
|
5332
5315
|
import("./assets/start-HeKLHD9b.js"),
|
|
5333
5316
|
import("./assets/__23tanstack-start-plugin-adapters-BzCA6dXo.js")
|
|
5334
5317
|
]);
|
package/bin/spiracha.js
ADDED
package/package.json
CHANGED
|
@@ -4,21 +4,21 @@
|
|
|
4
4
|
"url": "https://github.com/ragaeeb"
|
|
5
5
|
},
|
|
6
6
|
"bin": {
|
|
7
|
-
"codex-chats": "./
|
|
8
|
-
"codex-chats-claude": "./
|
|
9
|
-
"spiracha": "./
|
|
7
|
+
"codex-chats": "./bin/codex-chats.js",
|
|
8
|
+
"codex-chats-claude": "./bin/codex-chats-claude.js",
|
|
9
|
+
"spiracha": "./bin/spiracha.js"
|
|
10
10
|
},
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/ragaeeb/spiracha/issues"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@inquirer/prompts": "^8.
|
|
15
|
+
"@inquirer/prompts": "^8.5.0",
|
|
16
16
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
17
17
|
"@tanstack/react-query": "5.100.14",
|
|
18
18
|
"@tanstack/react-router": "1.170.8",
|
|
19
19
|
"@tanstack/react-router-ssr-query": "1.167.0",
|
|
20
20
|
"@tanstack/react-table": "8.21.3",
|
|
21
|
-
"@tanstack/react-virtual": "3.13.
|
|
21
|
+
"@tanstack/react-virtual": "3.13.26",
|
|
22
22
|
"class-variance-authority": "0.7.1",
|
|
23
23
|
"clsx": "2.1.1",
|
|
24
24
|
"iconv-lite": "^0.7.2",
|
|
@@ -39,6 +39,9 @@
|
|
|
39
39
|
"bun": ">=1.3.13"
|
|
40
40
|
},
|
|
41
41
|
"files": [
|
|
42
|
+
"bin/codex-chats.js",
|
|
43
|
+
"bin/codex-chats-claude.js",
|
|
44
|
+
"bin/spiracha.js",
|
|
42
45
|
"src/export-chats.ts",
|
|
43
46
|
"src/export-claude.ts",
|
|
44
47
|
"src/mcp-server.ts",
|
|
@@ -109,7 +112,7 @@
|
|
|
109
112
|
"ui:preview": "bun run --cwd apps/ui preview"
|
|
110
113
|
},
|
|
111
114
|
"type": "module",
|
|
112
|
-
"version": "1.
|
|
115
|
+
"version": "1.2.0",
|
|
113
116
|
"workspaces": [
|
|
114
117
|
"apps/*"
|
|
115
118
|
]
|
|
@@ -11,9 +11,9 @@ import { buildUiExportDownloadUrl, ensureUiExportDir } from './ui-export-files';
|
|
|
11
11
|
type RenderCodexThreadDownloadInput = {
|
|
12
12
|
dbPath: string;
|
|
13
13
|
includeCommentary: boolean;
|
|
14
|
+
includeMetadata: boolean;
|
|
14
15
|
includeTools: boolean;
|
|
15
16
|
largeExportThresholdBytes?: number;
|
|
16
|
-
optimized: boolean;
|
|
17
17
|
outputFormat: ExportFormat;
|
|
18
18
|
pathDisplaySettings?: Pick<PathDisplaySettings, 'convertToProjectRoot' | 'redactUsername'>;
|
|
19
19
|
publicExportDir?: string;
|
|
@@ -79,6 +79,17 @@ const buildUniqueArchivePath = (exportDir: string, exportBaseName: string) => {
|
|
|
79
79
|
return path.join(exportDir, `${exportBaseName}-${randomUUID()}.zip`);
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
const buildUniqueBatchEntryBaseName = (baseName: string, threadId: string, usedBaseNames: Set<string>): string => {
|
|
83
|
+
if (!usedBaseNames.has(baseName)) {
|
|
84
|
+
usedBaseNames.add(baseName);
|
|
85
|
+
return baseName;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const collisionSafeBaseName = `${baseName}-${threadId}`;
|
|
89
|
+
usedBaseNames.add(collisionSafeBaseName);
|
|
90
|
+
return collisionSafeBaseName;
|
|
91
|
+
};
|
|
92
|
+
|
|
82
93
|
type RolloutSnapshot = {
|
|
83
94
|
mtimeMs: number;
|
|
84
95
|
sizeBytes: number;
|
|
@@ -90,9 +101,9 @@ const toDownloadOptions = (input: RenderCodexThreadDownloadInput): CodexCliOptio
|
|
|
90
101
|
dbPath: input.dbPath,
|
|
91
102
|
flat: false,
|
|
92
103
|
includeCommentary: input.includeCommentary,
|
|
104
|
+
includeMetadata: input.includeMetadata,
|
|
93
105
|
includeTools: input.includeTools,
|
|
94
106
|
inputDir: '',
|
|
95
|
-
optimized: input.optimized,
|
|
96
107
|
outputDir: '',
|
|
97
108
|
outputFormat: input.outputFormat,
|
|
98
109
|
projectFilter: null,
|
|
@@ -340,6 +351,7 @@ export const renderCodexThreadsDownload = async (
|
|
|
340
351
|
const exportBaseName = buildBatchExportBaseName(threads);
|
|
341
352
|
const bundleDirectory = await createExportWorkspace(exportDir, exportBaseName);
|
|
342
353
|
const zipPath = buildUniqueArchivePath(exportDir, exportBaseName);
|
|
354
|
+
const usedBatchEntryBaseNames = new Set<string>();
|
|
343
355
|
|
|
344
356
|
logExportEvent('info', 'batch_start', {
|
|
345
357
|
exportBaseName,
|
|
@@ -352,8 +364,13 @@ export const renderCodexThreadsDownload = async (
|
|
|
352
364
|
for (const entry of browseEntries) {
|
|
353
365
|
const rolloutSnapshotBefore = await getRolloutSnapshot(entry.thread.rollout_path);
|
|
354
366
|
const singleBaseName = buildExportBaseName(entry.thread);
|
|
367
|
+
const uniqueBaseName = buildUniqueBatchEntryBaseName(
|
|
368
|
+
singleBaseName,
|
|
369
|
+
entry.thread.id,
|
|
370
|
+
usedBatchEntryBaseNames,
|
|
371
|
+
);
|
|
355
372
|
const extension = input.outputFormat === 'md' ? 'md' : 'txt';
|
|
356
|
-
const relativeFileName = `${
|
|
373
|
+
const relativeFileName = `${uniqueBaseName}.${extension}`;
|
|
357
374
|
const savedPath = path.join(bundleDirectory, relativeFileName);
|
|
358
375
|
const transform = (text: string) =>
|
|
359
376
|
input.pathDisplaySettings
|
|
@@ -363,6 +380,14 @@ export const renderCodexThreadsDownload = async (
|
|
|
363
380
|
})
|
|
364
381
|
: text;
|
|
365
382
|
|
|
383
|
+
if (uniqueBaseName !== singleBaseName) {
|
|
384
|
+
logExportEvent('warn', 'batch_entry_name_collision', {
|
|
385
|
+
resolvedFileName: relativeFileName,
|
|
386
|
+
singleBaseName,
|
|
387
|
+
threadId: entry.thread.id,
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
|
|
366
391
|
const saved = await writeSessionFileExport(
|
|
367
392
|
{
|
|
368
393
|
fallbackReason: null,
|
|
@@ -10,7 +10,7 @@ export const parseCodexCliArgs = (argv: string[]): CodexCliOptions => {
|
|
|
10
10
|
let projectFilter: string | null = null;
|
|
11
11
|
let threadIds: string[] = [];
|
|
12
12
|
let outputProvided = false;
|
|
13
|
-
let
|
|
13
|
+
let includeMetadata = true;
|
|
14
14
|
let includeCommentary = true;
|
|
15
15
|
let includeTools = false;
|
|
16
16
|
let outputFormat: ExportFormat = 'md';
|
|
@@ -22,9 +22,9 @@ export const parseCodexCliArgs = (argv: string[]): CodexCliOptions => {
|
|
|
22
22
|
dbPath,
|
|
23
23
|
flat,
|
|
24
24
|
includeCommentary,
|
|
25
|
+
includeMetadata,
|
|
25
26
|
includeTools,
|
|
26
27
|
inputDir,
|
|
27
|
-
optimized,
|
|
28
28
|
outputDir,
|
|
29
29
|
outputFormat,
|
|
30
30
|
outputProvided,
|
|
@@ -37,9 +37,9 @@ export const parseCodexCliArgs = (argv: string[]): CodexCliOptions => {
|
|
|
37
37
|
dbPath,
|
|
38
38
|
flat,
|
|
39
39
|
includeCommentary,
|
|
40
|
+
includeMetadata,
|
|
40
41
|
includeTools,
|
|
41
42
|
inputDir,
|
|
42
|
-
optimized,
|
|
43
43
|
outputDir,
|
|
44
44
|
outputFormat,
|
|
45
45
|
outputProvided,
|
|
@@ -58,9 +58,9 @@ export const parseCodexCliArgs = (argv: string[]): CodexCliOptions => {
|
|
|
58
58
|
dbPath,
|
|
59
59
|
flat,
|
|
60
60
|
includeCommentary,
|
|
61
|
+
includeMetadata,
|
|
61
62
|
includeTools,
|
|
62
63
|
inputDir,
|
|
63
|
-
optimized,
|
|
64
64
|
outputDir: outputDir ?? DEFAULT_OUTPUT_DIR,
|
|
65
65
|
outputFormat,
|
|
66
66
|
projectFilter,
|
|
@@ -73,9 +73,9 @@ type CodexCliState = {
|
|
|
73
73
|
dbPath: string;
|
|
74
74
|
flat: boolean;
|
|
75
75
|
includeCommentary: boolean;
|
|
76
|
+
includeMetadata: boolean;
|
|
76
77
|
includeTools: boolean;
|
|
77
78
|
inputDir: string;
|
|
78
|
-
optimized: boolean;
|
|
79
79
|
outputDir: string | null;
|
|
80
80
|
outputFormat: ExportFormat;
|
|
81
81
|
outputProvided: boolean;
|
|
@@ -142,12 +142,12 @@ const applyCodexCliArg = (argv: string[], index: number, state: CodexCliState):
|
|
|
142
142
|
};
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
if (arg === '--
|
|
145
|
+
if (arg === '--no-metadata') {
|
|
146
146
|
return {
|
|
147
147
|
index,
|
|
148
148
|
state: {
|
|
149
149
|
...state,
|
|
150
|
-
|
|
150
|
+
includeMetadata: false,
|
|
151
151
|
},
|
|
152
152
|
};
|
|
153
153
|
}
|
|
@@ -220,7 +220,7 @@ export const getCodexHelpText = (): string => {
|
|
|
220
220
|
'Usage:',
|
|
221
221
|
' codex-chats',
|
|
222
222
|
' codex-chats --interactive',
|
|
223
|
-
' codex-chats [--db FILE] [--input DIR] [--output DIR] [--cwd DIR] [--project NAME] [--
|
|
223
|
+
' codex-chats [--db FILE] [--input DIR] [--output DIR] [--cwd DIR] [--project NAME] [--no-metadata] [--tools] [--flat] [--output-format md|txt] [codex://threads/<thread-id> ...]',
|
|
224
224
|
'',
|
|
225
225
|
'Options:',
|
|
226
226
|
` --db Thread database path (default: ${DEFAULT_DB_PATH})`,
|
|
@@ -230,7 +230,7 @@ export const getCodexHelpText = (): string => {
|
|
|
230
230
|
' --project Only export chats whose cwd basename matches this project name',
|
|
231
231
|
' codex://threads/<id>',
|
|
232
232
|
' Only export the exact threads referenced by these Codex deeplinks',
|
|
233
|
-
' --
|
|
233
|
+
' --no-metadata Omit the chat metadata section from the export header',
|
|
234
234
|
' --tools Include tool-call logs such as exec_command invocations',
|
|
235
235
|
' --flat Write all exports into one folder instead of nested subfolders',
|
|
236
236
|
' --output-format Output file format: md or txt (default: md)',
|