claude-sessions-mcp 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-HK6PMHC3.js → chunk-7MUU7A32.js} +2 -2
- package/dist/chunk-7MUU7A32.js.map +1 -0
- package/dist/mcp/index.js +161 -20
- package/dist/mcp/index.js.map +1 -1
- package/dist/server.js +1 -1
- package/dist/web/client/_app/immutable/assets/0.CwJLztMb.css +1 -0
- package/dist/web/client/_app/immutable/assets/0.CwJLztMb.css.br +0 -0
- package/dist/web/client/_app/immutable/assets/0.CwJLztMb.css.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/{ChOgyrGO.js → CkKD22Ww.js} +2 -2
- package/dist/web/client/_app/immutable/chunks/CkKD22Ww.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/CkKD22Ww.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/{DbCO4Be8.js → DJ2XDlZh.js} +1 -1
- package/dist/web/client/_app/immutable/chunks/DJ2XDlZh.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/DJ2XDlZh.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/{B4TJWzDE.js → DUfrtY0h.js} +1 -1
- package/dist/web/client/_app/immutable/chunks/DUfrtY0h.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/DUfrtY0h.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/{9luERNGW.js → DecY8Lt_.js} +1 -1
- package/dist/web/client/_app/immutable/chunks/DecY8Lt_.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/DecY8Lt_.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/xvhGf2kv.js +1 -0
- package/dist/web/client/_app/immutable/chunks/xvhGf2kv.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/xvhGf2kv.js.gz +0 -0
- package/dist/web/client/_app/immutable/entry/{app.BnwskVL-.js → app.D9OMq4hT.js} +2 -2
- package/dist/web/client/_app/immutable/entry/app.D9OMq4hT.js.br +0 -0
- package/dist/web/client/_app/immutable/entry/app.D9OMq4hT.js.gz +0 -0
- package/dist/web/client/_app/immutable/entry/start.B8HX8ndm.js +1 -0
- package/dist/web/client/_app/immutable/entry/start.B8HX8ndm.js.br +2 -0
- package/dist/web/client/_app/immutable/entry/start.B8HX8ndm.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/0.BihBXfXC.js +1 -0
- package/dist/web/client/_app/immutable/nodes/0.BihBXfXC.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/0.BihBXfXC.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/{1.CoCWmd0q.js → 1.GzS0_vVo.js} +1 -1
- package/dist/web/client/_app/immutable/nodes/1.GzS0_vVo.js.br +2 -0
- package/dist/web/client/_app/immutable/nodes/1.GzS0_vVo.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/{2.DqJoUS41.js → 2.DLDvSy-I.js} +1 -1
- package/dist/web/client/_app/immutable/nodes/2.DLDvSy-I.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/2.DLDvSy-I.js.gz +0 -0
- package/dist/web/client/_app/version.json +1 -1
- package/dist/web/client/_app/version.json.br +0 -0
- package/dist/web/client/_app/version.json.gz +0 -0
- package/dist/web/server/chunks/{0-D_Gx_HFy.js → 0-CfWkxQMb.js} +4 -4
- package/dist/web/server/chunks/{0-D_Gx_HFy.js.map → 0-CfWkxQMb.js.map} +1 -1
- package/dist/web/server/chunks/{1-BNMjiqhE.js → 1-CYWeDRMQ.js} +2 -2
- package/dist/web/server/chunks/{1-BNMjiqhE.js.map → 1-CYWeDRMQ.js.map} +1 -1
- package/dist/web/server/chunks/{2-Bx262N6m.js → 2-CbCSzfAy.js} +2 -2
- package/dist/web/server/chunks/{2-Bx262N6m.js.map → 2-CbCSzfAy.js.map} +1 -1
- package/dist/web/server/chunks/{_layout.svelte-Dqh3cdpb.js → _layout.svelte-g4K2eFdi.js} +3 -2
- package/dist/web/server/chunks/_layout.svelte-g4K2eFdi.js.map +1 -0
- package/dist/web/server/chunks/_server.ts-Bw_uJ6TN.js +11 -0
- package/dist/web/server/chunks/_server.ts-Bw_uJ6TN.js.map +1 -0
- package/dist/web/server/chunks/exports-BzHwARwz.js.map +1 -1
- package/dist/web/server/chunks/index-CoD1IJuy.js.map +1 -1
- package/dist/web/server/index.js +184 -378
- package/dist/web/server/index.js.map +1 -1
- package/dist/web/server/manifest.js +11 -4
- package/dist/web/server/manifest.js.map +1 -1
- package/package.json +3 -2
- package/dist/chunk-HK6PMHC3.js.map +0 -1
- package/dist/web/client/_app/immutable/assets/0.BNKw18IQ.css +0 -1
- package/dist/web/client/_app/immutable/assets/0.BNKw18IQ.css.br +0 -0
- package/dist/web/client/_app/immutable/assets/0.BNKw18IQ.css.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/9luERNGW.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/9luERNGW.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/B4TJWzDE.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/B4TJWzDE.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/ChOgyrGO.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/ChOgyrGO.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/DUEukD6E.js +0 -1
- package/dist/web/client/_app/immutable/chunks/DUEukD6E.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/DUEukD6E.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/DbCO4Be8.js.br +0 -1
- package/dist/web/client/_app/immutable/chunks/DbCO4Be8.js.gz +0 -0
- package/dist/web/client/_app/immutable/entry/app.BnwskVL-.js.br +0 -0
- package/dist/web/client/_app/immutable/entry/app.BnwskVL-.js.gz +0 -0
- package/dist/web/client/_app/immutable/entry/start.CQ__ZoJ7.js +0 -1
- package/dist/web/client/_app/immutable/entry/start.CQ__ZoJ7.js.br +0 -0
- package/dist/web/client/_app/immutable/entry/start.CQ__ZoJ7.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/0.Cd8eOV9t.js +0 -1
- package/dist/web/client/_app/immutable/nodes/0.Cd8eOV9t.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/0.Cd8eOV9t.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/1.CoCWmd0q.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/1.CoCWmd0q.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/2.DqJoUS41.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/2.DqJoUS41.js.gz +0 -0
- package/dist/web/server/chunks/_layout.svelte-Dqh3cdpb.js.map +0 -1
|
@@ -4,7 +4,7 @@ import { fileURLToPath } from "url";
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
6
|
var webServerPath = path.join(__dirname, "web", "index.js");
|
|
7
|
-
async function startWebServer(port =
|
|
7
|
+
async function startWebServer(port = 5173, openBrowser = true) {
|
|
8
8
|
const child = spawn("node", [webServerPath], {
|
|
9
9
|
stdio: ["ignore", "pipe", "pipe"],
|
|
10
10
|
env: { ...process.env, PORT: String(port) }
|
|
@@ -44,4 +44,4 @@ export {
|
|
|
44
44
|
startWebServer,
|
|
45
45
|
stopWebServer
|
|
46
46
|
};
|
|
47
|
-
//# sourceMappingURL=chunk-
|
|
47
|
+
//# sourceMappingURL=chunk-7MUU7A32.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import { spawn, type ChildProcess } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport path from 'node:path'\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\n// dist/web/index.js is the built SvelteKit server (adapter-node)\nconst webServerPath = path.join(__dirname, 'web', 'index.js')\n\ninterface WebServer {\n process: ChildProcess\n port: number\n}\n\nexport async function startWebServer(\n port: number = 5173,\n openBrowser: boolean = true\n): Promise<WebServer> {\n // Run the built SvelteKit server directly with Node\n const child = spawn('node', [webServerPath], {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, PORT: String(port) },\n })\n\n // Wait for server to start\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => reject(new Error('Server startup timeout')), 10000)\n\n child.stdout?.on('data', (data: Buffer) => {\n const output = data.toString()\n // SvelteKit adapter-node outputs \"Listening on http://0.0.0.0:PORT\"\n if (\n output.includes('Listening on') ||\n output.includes('localhost') ||\n output.includes('Local:')\n ) {\n clearTimeout(timeout)\n resolve()\n }\n })\n\n child.on('error', (err) => {\n clearTimeout(timeout)\n reject(err)\n })\n\n child.on('exit', (code) => {\n if (code !== 0) {\n clearTimeout(timeout)\n reject(new Error(`Server exited with code ${code}`))\n }\n })\n })\n\n // Open browser if requested\n if (openBrowser) {\n const url = `http://localhost:${port}`\n const openCmd =\n process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'\n spawn(openCmd, [url], { stdio: 'ignore', detached: true }).unref()\n }\n\n return { process: child, port }\n}\n\nexport async function stopWebServer(server: WebServer): Promise<void> {\n server.process.kill('SIGTERM')\n}\n"],"mappings":";AAAA,SAAS,aAAgC;AACzC,SAAS,qBAAqB;AAC9B,OAAO,UAAU;AAEjB,IAAM,YAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAE7D,IAAM,gBAAgB,KAAK,KAAK,WAAW,OAAO,UAAU;AAO5D,eAAsB,eACpB,OAAe,MACf,cAAuB,MACH;AAEpB,QAAM,QAAQ,MAAM,QAAQ,CAAC,aAAa,GAAG;AAAA,IAC3C,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,IAChC,KAAK,EAAE,GAAG,QAAQ,KAAK,MAAM,OAAO,IAAI,EAAE;AAAA,EAC5C,CAAC;AAGD,QAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,UAAM,UAAU,WAAW,MAAM,OAAO,IAAI,MAAM,wBAAwB,CAAC,GAAG,GAAK;AAEnF,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACzC,YAAM,SAAS,KAAK,SAAS;AAE7B,UACE,OAAO,SAAS,cAAc,KAC9B,OAAO,SAAS,WAAW,KAC3B,OAAO,SAAS,QAAQ,GACxB;AACA,qBAAa,OAAO;AACpB,gBAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,QAAQ;AACzB,mBAAa,OAAO;AACpB,aAAO,GAAG;AAAA,IACZ,CAAC;AAED,UAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,UAAI,SAAS,GAAG;AACd,qBAAa,OAAO;AACpB,eAAO,IAAI,MAAM,2BAA2B,IAAI,EAAE,CAAC;AAAA,MACrD;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAGD,MAAI,aAAa;AACf,UAAM,MAAM,oBAAoB,IAAI;AACpC,UAAM,UACJ,QAAQ,aAAa,WAAW,SAAS,QAAQ,aAAa,UAAU,UAAU;AACpF,UAAM,SAAS,CAAC,GAAG,GAAG,EAAE,OAAO,UAAU,UAAU,KAAK,CAAC,EAAE,MAAM;AAAA,EACnE;AAEA,SAAO,EAAE,SAAS,OAAO,KAAK;AAChC;AAEA,eAAsB,cAAc,QAAkC;AACpE,SAAO,QAAQ,KAAK,SAAS;AAC/B;","names":[]}
|
package/dist/mcp/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
startWebServer,
|
|
4
4
|
stopWebServer
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-7MUU7A32.js";
|
|
6
6
|
|
|
7
7
|
// src/mcp/index.ts
|
|
8
8
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -80,6 +80,12 @@ var listSessions = (projectName) => Effect.gen(function* () {
|
|
|
80
80
|
);
|
|
81
81
|
return sessions;
|
|
82
82
|
});
|
|
83
|
+
var readSession = (projectName, sessionId) => Effect.gen(function* () {
|
|
84
|
+
const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`);
|
|
85
|
+
const content = yield* Effect.tryPromise(() => fs.readFile(filePath, "utf-8"));
|
|
86
|
+
const lines = content.trim().split("\n").filter(Boolean);
|
|
87
|
+
return lines.map((line) => JSON.parse(line));
|
|
88
|
+
});
|
|
83
89
|
var deleteSession = (projectName, sessionId) => Effect.gen(function* () {
|
|
84
90
|
const sessionsDir = getSessionsDir();
|
|
85
91
|
const filePath = path.join(sessionsDir, projectName, `${sessionId}.jsonl`);
|
|
@@ -167,6 +173,102 @@ var clearSessions = (options) => Effect.gen(function* () {
|
|
|
167
173
|
}
|
|
168
174
|
return { success: true, deletedCount };
|
|
169
175
|
});
|
|
176
|
+
var getSessionFiles = (projectName, sessionId) => Effect.gen(function* () {
|
|
177
|
+
const messages = yield* readSession(projectName, sessionId);
|
|
178
|
+
const fileChanges = [];
|
|
179
|
+
const seenFiles = /* @__PURE__ */ new Set();
|
|
180
|
+
for (const msg of messages) {
|
|
181
|
+
if (msg.type === "file-history-snapshot") {
|
|
182
|
+
const snapshot = msg;
|
|
183
|
+
const backups = snapshot.snapshot?.trackedFileBackups;
|
|
184
|
+
if (backups && typeof backups === "object") {
|
|
185
|
+
for (const filePath of Object.keys(backups)) {
|
|
186
|
+
if (!seenFiles.has(filePath)) {
|
|
187
|
+
seenFiles.add(filePath);
|
|
188
|
+
fileChanges.push({
|
|
189
|
+
path: filePath,
|
|
190
|
+
action: "modified",
|
|
191
|
+
timestamp: snapshot.snapshot?.timestamp,
|
|
192
|
+
messageUuid: snapshot.messageId ?? msg.uuid
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (msg.type === "assistant" && msg.message) {
|
|
199
|
+
const assistantMsg = msg.message;
|
|
200
|
+
const content = assistantMsg.content;
|
|
201
|
+
if (Array.isArray(content)) {
|
|
202
|
+
for (const block of content) {
|
|
203
|
+
if (block.type === "tool_use" && (block.name === "Write" || block.name === "Edit")) {
|
|
204
|
+
const filePath = block.input?.file_path;
|
|
205
|
+
if (filePath && !seenFiles.has(filePath)) {
|
|
206
|
+
seenFiles.add(filePath);
|
|
207
|
+
fileChanges.push({
|
|
208
|
+
path: filePath,
|
|
209
|
+
action: block.name === "Write" ? "created" : "modified",
|
|
210
|
+
timestamp: msg.timestamp,
|
|
211
|
+
messageUuid: msg.uuid
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
sessionId,
|
|
221
|
+
projectName,
|
|
222
|
+
files: fileChanges,
|
|
223
|
+
totalChanges: fileChanges.length
|
|
224
|
+
};
|
|
225
|
+
});
|
|
226
|
+
var getSessionDiffSummary = (projectName, sessionId) => Effect.gen(function* () {
|
|
227
|
+
const messages = yield* readSession(projectName, sessionId);
|
|
228
|
+
const title = pipe(
|
|
229
|
+
messages,
|
|
230
|
+
A.findFirst((m) => m.type === "human"),
|
|
231
|
+
O.map((m) => {
|
|
232
|
+
const msg = m.message;
|
|
233
|
+
const content = msg?.content ?? "";
|
|
234
|
+
return content.slice(0, 50) + (content.length > 50 ? "..." : "");
|
|
235
|
+
}),
|
|
236
|
+
O.getOrElse(() => "Untitled")
|
|
237
|
+
);
|
|
238
|
+
const changes = [];
|
|
239
|
+
const seenFiles = /* @__PURE__ */ new Set();
|
|
240
|
+
let snapshotCount = 0;
|
|
241
|
+
for (const msg of messages) {
|
|
242
|
+
if (msg.type === "file-history-snapshot") {
|
|
243
|
+
snapshotCount++;
|
|
244
|
+
const snapshot = msg;
|
|
245
|
+
const backups = snapshot.snapshot?.trackedFileBackups;
|
|
246
|
+
if (backups && typeof backups === "object") {
|
|
247
|
+
for (const [filePath, backup] of Object.entries(backups)) {
|
|
248
|
+
if (!seenFiles.has(filePath)) {
|
|
249
|
+
seenFiles.add(filePath);
|
|
250
|
+
const backupData = backup;
|
|
251
|
+
const content = backupData?.content ?? "";
|
|
252
|
+
changes.push({
|
|
253
|
+
path: filePath,
|
|
254
|
+
action: "modified",
|
|
255
|
+
hasBackup: content.length > 0,
|
|
256
|
+
backupPreview: content.slice(0, 100) + (content.length > 100 ? "..." : "")
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
sessionId,
|
|
265
|
+
projectName,
|
|
266
|
+
title,
|
|
267
|
+
changes,
|
|
268
|
+
totalFiles: changes.length,
|
|
269
|
+
snapshotCount
|
|
270
|
+
};
|
|
271
|
+
});
|
|
170
272
|
|
|
171
273
|
// src/mcp/index.ts
|
|
172
274
|
var server = new McpServer({
|
|
@@ -274,33 +376,67 @@ server.tool(
|
|
|
274
376
|
};
|
|
275
377
|
}
|
|
276
378
|
);
|
|
379
|
+
server.tool(
|
|
380
|
+
"get_session_files",
|
|
381
|
+
"Get list of all files changed in a session (from file-history-snapshot and tool_use)",
|
|
382
|
+
{
|
|
383
|
+
project_name: z.string().describe("Project folder name"),
|
|
384
|
+
session_id: z.string().describe("Session ID")
|
|
385
|
+
},
|
|
386
|
+
async ({ project_name, session_id }) => {
|
|
387
|
+
const result = await Effect2.runPromise(getSessionFiles(project_name, session_id));
|
|
388
|
+
return {
|
|
389
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
);
|
|
393
|
+
server.tool(
|
|
394
|
+
"get_session_diff",
|
|
395
|
+
"Get diff summary for a session including file changes and snapshot info",
|
|
396
|
+
{
|
|
397
|
+
project_name: z.string().describe("Project folder name"),
|
|
398
|
+
session_id: z.string().describe("Session ID")
|
|
399
|
+
},
|
|
400
|
+
async ({ project_name, session_id }) => {
|
|
401
|
+
const result = await Effect2.runPromise(getSessionDiffSummary(project_name, session_id));
|
|
402
|
+
return {
|
|
403
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
);
|
|
277
407
|
var webServerInstance = null;
|
|
278
408
|
server.tool(
|
|
279
409
|
"start_gui",
|
|
280
410
|
"Start the web GUI for session management and open it in browser",
|
|
281
411
|
{
|
|
282
|
-
port: z.number().default(
|
|
283
|
-
open_browser: z.boolean().default(true).describe("Whether to open browser automatically (default: true)")
|
|
412
|
+
port: z.number().default(5173).describe("Port to run the web server on (default: 5173)"),
|
|
413
|
+
open_browser: z.boolean().default(true).describe("Whether to open browser automatically (default: true)"),
|
|
414
|
+
restart: z.boolean().default(false).describe("Restart the server if already running (default: false)")
|
|
284
415
|
},
|
|
285
|
-
async ({ port, open_browser }) => {
|
|
416
|
+
async ({ port, open_browser, restart }) => {
|
|
286
417
|
try {
|
|
287
418
|
if (webServerInstance) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
419
|
+
if (restart) {
|
|
420
|
+
await stopWebServer(webServerInstance);
|
|
421
|
+
webServerInstance = null;
|
|
422
|
+
} else {
|
|
423
|
+
return {
|
|
424
|
+
content: [
|
|
425
|
+
{
|
|
426
|
+
type: "text",
|
|
427
|
+
text: JSON.stringify(
|
|
428
|
+
{
|
|
429
|
+
success: true,
|
|
430
|
+
message: "Web GUI is already running",
|
|
431
|
+
url: `http://localhost:${port}`
|
|
432
|
+
},
|
|
433
|
+
null,
|
|
434
|
+
2
|
|
435
|
+
)
|
|
436
|
+
}
|
|
437
|
+
]
|
|
438
|
+
};
|
|
439
|
+
}
|
|
304
440
|
}
|
|
305
441
|
webServerInstance = await startWebServer(port, open_browser);
|
|
306
442
|
return {
|
|
@@ -341,6 +477,11 @@ server.tool(
|
|
|
341
477
|
);
|
|
342
478
|
server.tool("stop_gui", "Stop the web GUI server", {}, async () => {
|
|
343
479
|
if (webServerInstance) {
|
|
480
|
+
const port = webServerInstance.port;
|
|
481
|
+
try {
|
|
482
|
+
await fetch(`http://localhost:${port}/api/shutdown`, { method: "POST" });
|
|
483
|
+
} catch {
|
|
484
|
+
}
|
|
344
485
|
await stopWebServer(webServerInstance);
|
|
345
486
|
webServerInstance = null;
|
|
346
487
|
return {
|
package/dist/mcp/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/mcp/index.ts","../../src/lib/session.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { Effect } from 'effect'\nimport { z } from 'zod'\nimport * as session from '../lib/session.js'\nimport { startWebServer, stopWebServer } from '../server.js'\n\nconst server = new McpServer({\n name: 'claude-sessions-mcp',\n version: '0.1.0',\n})\n\n// List all projects\nserver.tool('list_projects', 'List all Claude Code projects with session counts', {}, async () => {\n const result = await Effect.runPromise(session.listProjects)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n})\n\n// List sessions in a project\nserver.tool(\n 'list_sessions',\n 'List all sessions in a project',\n {\n project_name: z.string().describe(\"Project folder name (e.g., '-Users-young-works-myproject')\"),\n },\n async ({ project_name }) => {\n const result = await Effect.runPromise(session.listSessions(project_name))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Rename session\nserver.tool(\n 'rename_session',\n 'Rename a session by adding a title prefix to the first message',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID (filename without .jsonl)'),\n new_title: z.string().describe('New title to add as prefix'),\n },\n async ({ project_name, session_id, new_title }) => {\n const result = await Effect.runPromise(\n session.renameSession(project_name, session_id, new_title)\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Delete session\nserver.tool(\n 'delete_session',\n 'Delete a session (moves to .bak folder for recovery)',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID to delete'),\n },\n async ({ project_name, session_id }) => {\n const result = await Effect.runPromise(session.deleteSession(project_name, session_id))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Delete message\nserver.tool(\n 'delete_message',\n 'Delete a message from a session and repair the parentUuid chain',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n message_uuid: z.string().describe('UUID of the message to delete'),\n },\n async ({ project_name, session_id, message_uuid }) => {\n const result = await Effect.runPromise(\n session.deleteMessage(project_name, session_id, message_uuid)\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Preview cleanup\nserver.tool(\n 'preview_cleanup',\n 'Preview sessions that would be cleaned (empty and invalid API key sessions)',\n {\n project_name: z.string().optional().describe('Optional: filter by project name'),\n },\n async ({ project_name }) => {\n const result = await Effect.runPromise(session.previewCleanup(project_name))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Clear sessions\nserver.tool(\n 'clear_sessions',\n 'Delete all empty sessions and invalid API key sessions',\n {\n project_name: z.string().optional().describe('Optional: filter by project name'),\n clear_empty: z.boolean().default(true).describe('Clear empty sessions (default: true)'),\n clear_invalid: z\n .boolean()\n .default(true)\n .describe('Clear invalid API key sessions (default: true)'),\n },\n async ({ project_name, clear_empty, clear_invalid }) => {\n const result = await Effect.runPromise(\n session.clearSessions({\n projectName: project_name,\n clearEmpty: clear_empty,\n clearInvalid: clear_invalid,\n })\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Start GUI\nlet webServerInstance: Awaited<ReturnType<typeof startWebServer>> | null = null\n\nserver.tool(\n 'start_gui',\n 'Start the web GUI for session management and open it in browser',\n {\n port: z.number().default(3000).describe('Port to run the web server on (default: 3000)'),\n open_browser: z\n .boolean()\n .default(true)\n .describe('Whether to open browser automatically (default: true)'),\n },\n async ({ port, open_browser }) => {\n try {\n if (webServerInstance) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n message: 'Web GUI is already running',\n url: `http://localhost:${port}`,\n },\n null,\n 2\n ),\n },\n ],\n }\n }\n\n webServerInstance = await startWebServer(port, open_browser)\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n message: 'Web GUI started successfully',\n url: `http://localhost:${port}`,\n pid: process.pid,\n },\n null,\n 2\n ),\n },\n ],\n }\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: false,\n error: String(error),\n },\n null,\n 2\n ),\n },\n ],\n }\n }\n }\n)\n\n// Stop GUI\nserver.tool('stop_gui', 'Stop the web GUI server', {}, async () => {\n if (webServerInstance) {\n await stopWebServer(webServerInstance)\n webServerInstance = null\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ success: true, message: 'Web GUI stopped successfully' }, null, 2),\n },\n ],\n }\n }\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ success: true, message: 'Web GUI was not running' }, null, 2),\n },\n ],\n }\n})\n\n// Main entry\nasync function main() {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n\nmain().catch(console.error)\n","import { Effect, pipe, Array as A, Option as O } from 'effect'\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport type { Message, SessionMeta, Project } from './schema.js'\n\n// Get Claude sessions directory\nexport const getSessionsDir = (): string => path.join(os.homedir(), '.claude', 'projects')\n\n// List all project directories\nexport const listProjects = Effect.gen(function* () {\n const sessionsDir = getSessionsDir()\n\n const exists = yield* Effect.tryPromise(() =>\n fs\n .access(sessionsDir)\n .then(() => true)\n .catch(() => false)\n )\n\n if (!exists) {\n return [] as Project[]\n }\n\n const entries = yield* Effect.tryPromise(() => fs.readdir(sessionsDir, { withFileTypes: true }))\n\n const projects = yield* Effect.all(\n entries\n .filter((e) => e.isDirectory())\n .map((entry) =>\n Effect.gen(function* () {\n const projectPath = path.join(sessionsDir, entry.name)\n const files = yield* Effect.tryPromise(() => fs.readdir(projectPath))\n const sessionFiles = files.filter((f) => f.endsWith('.jsonl'))\n\n return {\n name: entry.name,\n path: projectPath,\n sessionCount: sessionFiles.length,\n } satisfies Project\n })\n ),\n { concurrency: 10 }\n )\n\n return projects\n})\n\n// List sessions in a project\nexport const listSessions = (projectName: string) =>\n Effect.gen(function* () {\n const projectPath = path.join(getSessionsDir(), projectName)\n const files = yield* Effect.tryPromise(() => fs.readdir(projectPath))\n const sessionFiles = files.filter((f) => f.endsWith('.jsonl'))\n\n const sessions = yield* Effect.all(\n sessionFiles.map((file) =>\n Effect.gen(function* () {\n const filePath = path.join(projectPath, file)\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, 'utf-8'))\n const lines = content.trim().split('\\n').filter(Boolean)\n const messages = lines.map((line) => JSON.parse(line) as Message)\n\n const sessionId = file.replace('.jsonl', '')\n const firstMessage = messages[0]\n const lastMessage = messages[messages.length - 1]\n\n // Extract title from first user message\n const title = pipe(\n messages,\n A.findFirst((m) => m.type === 'human'),\n O.map((m) => {\n const msg = m.message as { content?: string } | undefined\n const content = msg?.content ?? ''\n return content.slice(0, 50) + (content.length > 50 ? '...' : '')\n }),\n O.getOrElse(() => 'Untitled')\n )\n\n return {\n id: sessionId,\n projectName,\n title,\n messageCount: messages.length,\n createdAt: firstMessage?.timestamp,\n updatedAt: lastMessage?.timestamp,\n } satisfies SessionMeta\n })\n ),\n { concurrency: 10 }\n )\n\n return sessions\n })\n\n// Read session messages\nexport const readSession = (projectName: string, sessionId: string) =>\n Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`)\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, 'utf-8'))\n const lines = content.trim().split('\\n').filter(Boolean)\n return lines.map((line) => JSON.parse(line) as Message)\n })\n\n// Delete a session\nexport const deleteSession = (projectName: string, sessionId: string) =>\n Effect.gen(function* () {\n const sessionsDir = getSessionsDir()\n const filePath = path.join(sessionsDir, projectName, `${sessionId}.jsonl`)\n\n // Create backup directory\n const backupDir = path.join(sessionsDir, projectName, '.bak')\n yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }))\n\n // Move to backup\n const backupPath = path.join(backupDir, `${sessionId}.jsonl`)\n yield* Effect.tryPromise(() => fs.rename(filePath, backupPath))\n\n return { success: true, backupPath }\n })\n\n// Rename session by adding title prefix\nexport const renameSession = (projectName: string, sessionId: string, newTitle: string) =>\n Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`)\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, 'utf-8'))\n const lines = content.trim().split('\\n').filter(Boolean)\n\n if (lines.length === 0) {\n return { success: false, error: 'Empty session' }\n }\n\n const messages = lines.map((line) => JSON.parse(line) as Message)\n const firstMsg = messages[0]\n\n // Add title prefix to first message\n if (firstMsg && typeof firstMsg.message === 'object' && firstMsg.message !== null) {\n const msg = firstMsg.message as { content?: string }\n if (msg.content) {\n // Remove existing title prefix if any\n const cleanContent = msg.content.replace(/^\\[.*?\\]\\s*/, '')\n msg.content = `[${newTitle}] ${cleanContent}`\n }\n }\n\n const newContent = messages.map((m) => JSON.stringify(m)).join('\\n') + '\\n'\n yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, 'utf-8'))\n\n return { success: true }\n })\n\n// Delete a message from session\nexport const deleteMessage = (projectName: string, sessionId: string, messageUuid: string) =>\n Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`)\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, 'utf-8'))\n const lines = content.trim().split('\\n').filter(Boolean)\n const messages = lines.map((line) => JSON.parse(line) as Message)\n\n const targetIndex = messages.findIndex((m) => m.uuid === messageUuid)\n if (targetIndex === -1) {\n return { success: false, error: 'Message not found' }\n }\n\n // Get the parent UUID of deleted message\n const deletedMsg = messages[targetIndex]\n const parentUuid = deletedMsg?.parentUuid\n\n // Update child message to point to deleted message's parent\n const nextMsg = messages[targetIndex + 1]\n if (nextMsg) {\n nextMsg.parentUuid = parentUuid\n }\n\n // Remove the message\n messages.splice(targetIndex, 1)\n\n const newContent = messages.map((m) => JSON.stringify(m)).join('\\n') + '\\n'\n yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, 'utf-8'))\n\n return { success: true }\n })\n\n// Preview cleanup - find empty and invalid sessions\nexport const previewCleanup = (projectName?: string) =>\n Effect.gen(function* () {\n const projects = yield* listProjects\n const targetProjects = projectName ? projects.filter((p) => p.name === projectName) : projects\n\n const results = yield* Effect.all(\n targetProjects.map((project) =>\n Effect.gen(function* () {\n const sessions = yield* listSessions(project.name)\n const emptySessions = sessions.filter((s) => s.messageCount === 0)\n const invalidSessions = sessions.filter(\n (s) => s.title?.includes('Invalid API key') || s.title?.includes('API key')\n )\n\n return {\n project: project.name,\n emptySessions,\n invalidSessions,\n }\n })\n ),\n { concurrency: 5 }\n )\n\n return results\n })\n\n// Clear sessions (empty and invalid)\nexport const clearSessions = (options: {\n projectName?: string\n clearEmpty?: boolean\n clearInvalid?: boolean\n}) =>\n Effect.gen(function* () {\n const { projectName, clearEmpty = true, clearInvalid = true } = options\n const cleanupPreview = yield* previewCleanup(projectName)\n\n let deletedCount = 0\n\n for (const result of cleanupPreview) {\n const toDelete = [\n ...(clearEmpty ? result.emptySessions : []),\n ...(clearInvalid ? result.invalidSessions : []),\n ]\n\n for (const session of toDelete) {\n yield* deleteSession(result.project, session.id)\n deletedCount++\n }\n }\n\n return { success: true, deletedCount }\n })\n"],"mappings":";;;;;;;AACA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,UAAAA,eAAc;AACvB,SAAS,SAAS;;;ACJlB,SAAS,QAAQ,MAAM,SAAS,GAAG,UAAU,SAAS;AACtD,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,YAAY,QAAQ;AAIb,IAAM,iBAAiB,MAAmB,UAAQ,WAAQ,GAAG,WAAW,UAAU;AAGlF,IAAM,eAAe,OAAO,IAAI,aAAa;AAClD,QAAM,cAAc,eAAe;AAEnC,QAAM,SAAS,OAAO,OAAO;AAAA,IAAW,MAEnC,UAAO,WAAW,EAClB,KAAK,MAAM,IAAI,EACf,MAAM,MAAM,KAAK;AAAA,EACtB;AAEA,MAAI,CAAC,QAAQ;AACX,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAU,OAAO,OAAO,WAAW,MAAS,WAAQ,aAAa,EAAE,eAAe,KAAK,CAAC,CAAC;AAE/F,QAAM,WAAW,OAAO,OAAO;AAAA,IAC7B,QACG,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,EAC7B;AAAA,MAAI,CAAC,UACJ,OAAO,IAAI,aAAa;AACtB,cAAM,cAAmB,UAAK,aAAa,MAAM,IAAI;AACrD,cAAM,QAAQ,OAAO,OAAO,WAAW,MAAS,WAAQ,WAAW,CAAC;AACpE,cAAM,eAAe,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,CAAC;AAE7D,eAAO;AAAA,UACL,MAAM,MAAM;AAAA,UACZ,MAAM;AAAA,UACN,cAAc,aAAa;AAAA,QAC7B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACF,EAAE,aAAa,GAAG;AAAA,EACpB;AAEA,SAAO;AACT,CAAC;AAGM,IAAM,eAAe,CAAC,gBAC3B,OAAO,IAAI,aAAa;AACtB,QAAM,cAAmB,UAAK,eAAe,GAAG,WAAW;AAC3D,QAAM,QAAQ,OAAO,OAAO,WAAW,MAAS,WAAQ,WAAW,CAAC;AACpE,QAAM,eAAe,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,CAAC;AAE7D,QAAM,WAAW,OAAO,OAAO;AAAA,IAC7B,aAAa;AAAA,MAAI,CAAC,SAChB,OAAO,IAAI,aAAa;AACtB,cAAM,WAAgB,UAAK,aAAa,IAAI;AAC5C,cAAM,UAAU,OAAO,OAAO,WAAW,MAAS,YAAS,UAAU,OAAO,CAAC;AAC7E,cAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AACvD,cAAM,WAAW,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,CAAY;AAEhE,cAAM,YAAY,KAAK,QAAQ,UAAU,EAAE;AAC3C,cAAM,eAAe,SAAS,CAAC;AAC/B,cAAM,cAAc,SAAS,SAAS,SAAS,CAAC;AAGhD,cAAM,QAAQ;AAAA,UACZ;AAAA,UACA,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,OAAO;AAAA,UACrC,EAAE,IAAI,CAAC,MAAM;AACX,kBAAM,MAAM,EAAE;AACd,kBAAMC,WAAU,KAAK,WAAW;AAChC,mBAAOA,SAAQ,MAAM,GAAG,EAAE,KAAKA,SAAQ,SAAS,KAAK,QAAQ;AAAA,UAC/D,CAAC;AAAA,UACD,EAAE,UAAU,MAAM,UAAU;AAAA,QAC9B;AAEA,eAAO;AAAA,UACL,IAAI;AAAA,UACJ;AAAA,UACA;AAAA,UACA,cAAc,SAAS;AAAA,UACvB,WAAW,cAAc;AAAA,UACzB,WAAW,aAAa;AAAA,QAC1B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,EAAE,aAAa,GAAG;AAAA,EACpB;AAEA,SAAO;AACT,CAAC;AAYI,IAAM,gBAAgB,CAAC,aAAqB,cACjD,OAAO,IAAI,aAAa;AACtB,QAAM,cAAc,eAAe;AACnC,QAAM,WAAgB,UAAK,aAAa,aAAa,GAAG,SAAS,QAAQ;AAGzE,QAAM,YAAiB,UAAK,aAAa,aAAa,MAAM;AAC5D,SAAO,OAAO,WAAW,MAAS,SAAM,WAAW,EAAE,WAAW,KAAK,CAAC,CAAC;AAGvE,QAAM,aAAkB,UAAK,WAAW,GAAG,SAAS,QAAQ;AAC5D,SAAO,OAAO,WAAW,MAAS,UAAO,UAAU,UAAU,CAAC;AAE9D,SAAO,EAAE,SAAS,MAAM,WAAW;AACrC,CAAC;AAGI,IAAM,gBAAgB,CAAC,aAAqB,WAAmB,aACpE,OAAO,IAAI,aAAa;AACtB,QAAM,WAAgB,UAAK,eAAe,GAAG,aAAa,GAAG,SAAS,QAAQ;AAC9E,QAAM,UAAU,OAAO,OAAO,WAAW,MAAS,YAAS,UAAU,OAAO,CAAC;AAC7E,QAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AAEvD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,EAAE,SAAS,OAAO,OAAO,gBAAgB;AAAA,EAClD;AAEA,QAAM,WAAW,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,CAAY;AAChE,QAAM,WAAW,SAAS,CAAC;AAG3B,MAAI,YAAY,OAAO,SAAS,YAAY,YAAY,SAAS,YAAY,MAAM;AACjF,UAAM,MAAM,SAAS;AACrB,QAAI,IAAI,SAAS;AAEf,YAAM,eAAe,IAAI,QAAQ,QAAQ,eAAe,EAAE;AAC1D,UAAI,UAAU,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,aAAa,SAAS,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AACvE,SAAO,OAAO,WAAW,MAAS,aAAU,UAAU,YAAY,OAAO,CAAC;AAE1E,SAAO,EAAE,SAAS,KAAK;AACzB,CAAC;AAGI,IAAM,gBAAgB,CAAC,aAAqB,WAAmB,gBACpE,OAAO,IAAI,aAAa;AACtB,QAAM,WAAgB,UAAK,eAAe,GAAG,aAAa,GAAG,SAAS,QAAQ;AAC9E,QAAM,UAAU,OAAO,OAAO,WAAW,MAAS,YAAS,UAAU,OAAO,CAAC;AAC7E,QAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AACvD,QAAM,WAAW,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,CAAY;AAEhE,QAAM,cAAc,SAAS,UAAU,CAAC,MAAM,EAAE,SAAS,WAAW;AACpE,MAAI,gBAAgB,IAAI;AACtB,WAAO,EAAE,SAAS,OAAO,OAAO,oBAAoB;AAAA,EACtD;AAGA,QAAM,aAAa,SAAS,WAAW;AACvC,QAAM,aAAa,YAAY;AAG/B,QAAM,UAAU,SAAS,cAAc,CAAC;AACxC,MAAI,SAAS;AACX,YAAQ,aAAa;AAAA,EACvB;AAGA,WAAS,OAAO,aAAa,CAAC;AAE9B,QAAM,aAAa,SAAS,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AACvE,SAAO,OAAO,WAAW,MAAS,aAAU,UAAU,YAAY,OAAO,CAAC;AAE1E,SAAO,EAAE,SAAS,KAAK;AACzB,CAAC;AAGI,IAAM,iBAAiB,CAAC,gBAC7B,OAAO,IAAI,aAAa;AACtB,QAAM,WAAW,OAAO;AACxB,QAAM,iBAAiB,cAAc,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,WAAW,IAAI;AAEtF,QAAM,UAAU,OAAO,OAAO;AAAA,IAC5B,eAAe;AAAA,MAAI,CAAC,YAClB,OAAO,IAAI,aAAa;AACtB,cAAM,WAAW,OAAO,aAAa,QAAQ,IAAI;AACjD,cAAM,gBAAgB,SAAS,OAAO,CAAC,MAAM,EAAE,iBAAiB,CAAC;AACjE,cAAM,kBAAkB,SAAS;AAAA,UAC/B,CAAC,MAAM,EAAE,OAAO,SAAS,iBAAiB,KAAK,EAAE,OAAO,SAAS,SAAS;AAAA,QAC5E;AAEA,eAAO;AAAA,UACL,SAAS,QAAQ;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,EAAE,aAAa,EAAE;AAAA,EACnB;AAEA,SAAO;AACT,CAAC;AAGI,IAAM,gBAAgB,CAAC,YAK5B,OAAO,IAAI,aAAa;AACtB,QAAM,EAAE,aAAa,aAAa,MAAM,eAAe,KAAK,IAAI;AAChE,QAAM,iBAAiB,OAAO,eAAe,WAAW;AAExD,MAAI,eAAe;AAEnB,aAAW,UAAU,gBAAgB;AACnC,UAAM,WAAW;AAAA,MACf,GAAI,aAAa,OAAO,gBAAgB,CAAC;AAAA,MACzC,GAAI,eAAe,OAAO,kBAAkB,CAAC;AAAA,IAC/C;AAEA,eAAW,WAAW,UAAU;AAC9B,aAAO,cAAc,OAAO,SAAS,QAAQ,EAAE;AAC/C;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,MAAM,aAAa;AACvC,CAAC;;;ADpOH,IAAM,SAAS,IAAI,UAAU;AAAA,EAC3B,MAAM;AAAA,EACN,SAAS;AACX,CAAC;AAGD,OAAO,KAAK,iBAAiB,qDAAqD,CAAC,GAAG,YAAY;AAChG,QAAM,SAAS,MAAMC,QAAO,WAAmB,YAAY;AAC3D,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,EACnE;AACF,CAAC;AAGD,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,4DAA4D;AAAA,EAChG;AAAA,EACA,OAAO,EAAE,aAAa,MAAM;AAC1B,UAAM,SAAS,MAAMA,QAAO,WAAmB,aAAa,YAAY,CAAC;AACzE,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,IACvD,YAAY,EAAE,OAAO,EAAE,SAAS,sCAAsC;AAAA,IACtE,WAAW,EAAE,OAAO,EAAE,SAAS,4BAA4B;AAAA,EAC7D;AAAA,EACA,OAAO,EAAE,cAAc,YAAY,UAAU,MAAM;AACjD,UAAM,SAAS,MAAMA,QAAO;AAAA,MAClB,cAAc,cAAc,YAAY,SAAS;AAAA,IAC3D;AACA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,IACvD,YAAY,EAAE,OAAO,EAAE,SAAS,sBAAsB;AAAA,EACxD;AAAA,EACA,OAAO,EAAE,cAAc,WAAW,MAAM;AACtC,UAAM,SAAS,MAAMA,QAAO,WAAmB,cAAc,cAAc,UAAU,CAAC;AACtF,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,IACvD,YAAY,EAAE,OAAO,EAAE,SAAS,YAAY;AAAA,IAC5C,cAAc,EAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,EACnE;AAAA,EACA,OAAO,EAAE,cAAc,YAAY,aAAa,MAAM;AACpD,UAAM,SAAS,MAAMA,QAAO;AAAA,MAClB,cAAc,cAAc,YAAY,YAAY;AAAA,IAC9D;AACA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,EACjF;AAAA,EACA,OAAO,EAAE,aAAa,MAAM;AAC1B,UAAM,SAAS,MAAMA,QAAO,WAAmB,eAAe,YAAY,CAAC;AAC3E,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,IAC/E,aAAa,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,sCAAsC;AAAA,IACtF,eAAe,EACZ,QAAQ,EACR,QAAQ,IAAI,EACZ,SAAS,gDAAgD;AAAA,EAC9D;AAAA,EACA,OAAO,EAAE,cAAc,aAAa,cAAc,MAAM;AACtD,UAAM,SAAS,MAAMA,QAAO;AAAA,MAClB,cAAc;AAAA,QACpB,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AACA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,IAAI,oBAAuE;AAE3E,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAI,EAAE,SAAS,+CAA+C;AAAA,IACvF,cAAc,EACX,QAAQ,EACR,QAAQ,IAAI,EACZ,SAAS,uDAAuD;AAAA,EACrE;AAAA,EACA,OAAO,EAAE,MAAM,aAAa,MAAM;AAChC,QAAI;AACF,UAAI,mBAAmB;AACrB,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,KAAK;AAAA,gBACT;AAAA,kBACE,SAAS;AAAA,kBACT,SAAS;AAAA,kBACT,KAAK,oBAAoB,IAAI;AAAA,gBAC/B;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,0BAAoB,MAAM,eAAe,MAAM,YAAY;AAE3D,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,KAAK;AAAA,cACT;AAAA,gBACE,SAAS;AAAA,gBACT,SAAS;AAAA,gBACT,KAAK,oBAAoB,IAAI;AAAA,gBAC7B,KAAK,QAAQ;AAAA,cACf;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,KAAK;AAAA,cACT;AAAA,gBACE,SAAS;AAAA,gBACT,OAAO,OAAO,KAAK;AAAA,cACrB;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAGA,OAAO,KAAK,YAAY,2BAA2B,CAAC,GAAG,YAAY;AACjE,MAAI,mBAAmB;AACrB,UAAM,cAAc,iBAAiB;AACrC,wBAAoB;AACpB,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,UAAU,EAAE,SAAS,MAAM,SAAS,+BAA+B,GAAG,MAAM,CAAC;AAAA,QAC1F;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU,EAAE,SAAS,MAAM,SAAS,0BAA0B,GAAG,MAAM,CAAC;AAAA,MACrF;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAGD,eAAe,OAAO;AACpB,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK,EAAE,MAAM,QAAQ,KAAK;","names":["Effect","content","Effect"]}
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/index.ts","../../src/lib/session.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { Effect } from 'effect'\nimport { z } from 'zod'\nimport * as session from '../lib/session.js'\nimport { startWebServer, stopWebServer } from '../server.js'\n\nconst server = new McpServer({\n name: 'claude-sessions-mcp',\n version: '0.1.0',\n})\n\n// List all projects\nserver.tool('list_projects', 'List all Claude Code projects with session counts', {}, async () => {\n const result = await Effect.runPromise(session.listProjects)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n})\n\n// List sessions in a project\nserver.tool(\n 'list_sessions',\n 'List all sessions in a project',\n {\n project_name: z.string().describe(\"Project folder name (e.g., '-Users-young-works-myproject')\"),\n },\n async ({ project_name }) => {\n const result = await Effect.runPromise(session.listSessions(project_name))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Rename session\nserver.tool(\n 'rename_session',\n 'Rename a session by adding a title prefix to the first message',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID (filename without .jsonl)'),\n new_title: z.string().describe('New title to add as prefix'),\n },\n async ({ project_name, session_id, new_title }) => {\n const result = await Effect.runPromise(\n session.renameSession(project_name, session_id, new_title)\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Delete session\nserver.tool(\n 'delete_session',\n 'Delete a session (moves to .bak folder for recovery)',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID to delete'),\n },\n async ({ project_name, session_id }) => {\n const result = await Effect.runPromise(session.deleteSession(project_name, session_id))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Delete message\nserver.tool(\n 'delete_message',\n 'Delete a message from a session and repair the parentUuid chain',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n message_uuid: z.string().describe('UUID of the message to delete'),\n },\n async ({ project_name, session_id, message_uuid }) => {\n const result = await Effect.runPromise(\n session.deleteMessage(project_name, session_id, message_uuid)\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Preview cleanup\nserver.tool(\n 'preview_cleanup',\n 'Preview sessions that would be cleaned (empty and invalid API key sessions)',\n {\n project_name: z.string().optional().describe('Optional: filter by project name'),\n },\n async ({ project_name }) => {\n const result = await Effect.runPromise(session.previewCleanup(project_name))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Clear sessions\nserver.tool(\n 'clear_sessions',\n 'Delete all empty sessions and invalid API key sessions',\n {\n project_name: z.string().optional().describe('Optional: filter by project name'),\n clear_empty: z.boolean().default(true).describe('Clear empty sessions (default: true)'),\n clear_invalid: z\n .boolean()\n .default(true)\n .describe('Clear invalid API key sessions (default: true)'),\n },\n async ({ project_name, clear_empty, clear_invalid }) => {\n const result = await Effect.runPromise(\n session.clearSessions({\n projectName: project_name,\n clearEmpty: clear_empty,\n clearInvalid: clear_invalid,\n })\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Get changed files from a session\nserver.tool(\n 'get_session_files',\n 'Get list of all files changed in a session (from file-history-snapshot and tool_use)',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n },\n async ({ project_name, session_id }) => {\n const result = await Effect.runPromise(session.getSessionFiles(project_name, session_id))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Get session diff summary\nserver.tool(\n 'get_session_diff',\n 'Get diff summary for a session including file changes and snapshot info',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n },\n async ({ project_name, session_id }) => {\n const result = await Effect.runPromise(session.getSessionDiffSummary(project_name, session_id))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Start GUI\nlet webServerInstance: Awaited<ReturnType<typeof startWebServer>> | null = null\n\nserver.tool(\n 'start_gui',\n 'Start the web GUI for session management and open it in browser',\n {\n port: z.number().default(5173).describe('Port to run the web server on (default: 5173)'),\n open_browser: z\n .boolean()\n .default(true)\n .describe('Whether to open browser automatically (default: true)'),\n restart: z\n .boolean()\n .default(false)\n .describe('Restart the server if already running (default: false)'),\n },\n async ({ port, open_browser, restart }) => {\n try {\n if (webServerInstance) {\n if (restart) {\n await stopWebServer(webServerInstance)\n webServerInstance = null\n } else {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n message: 'Web GUI is already running',\n url: `http://localhost:${port}`,\n },\n null,\n 2\n ),\n },\n ],\n }\n }\n }\n\n webServerInstance = await startWebServer(port, open_browser)\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n message: 'Web GUI started successfully',\n url: `http://localhost:${port}`,\n pid: process.pid,\n },\n null,\n 2\n ),\n },\n ],\n }\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: false,\n error: String(error),\n },\n null,\n 2\n ),\n },\n ],\n }\n }\n }\n)\n\n// Stop GUI\nserver.tool('stop_gui', 'Stop the web GUI server', {}, async () => {\n if (webServerInstance) {\n const port = webServerInstance.port\n // Call shutdown API first for graceful shutdown\n try {\n await fetch(`http://localhost:${port}/api/shutdown`, { method: 'POST' })\n } catch {\n // Server might already be stopping\n }\n // Then kill the process if still running\n await stopWebServer(webServerInstance)\n webServerInstance = null\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ success: true, message: 'Web GUI stopped successfully' }, null, 2),\n },\n ],\n }\n }\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ success: true, message: 'Web GUI was not running' }, null, 2),\n },\n ],\n }\n})\n\n// Main entry\nasync function main() {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n\nmain().catch(console.error)\n","import { Effect, pipe, Array as A, Option as O } from 'effect'\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport type { Message, SessionMeta, Project } from './schema.js'\n\n// Get Claude sessions directory\nexport const getSessionsDir = (): string => path.join(os.homedir(), '.claude', 'projects')\n\n// List all project directories\nexport const listProjects = Effect.gen(function* () {\n const sessionsDir = getSessionsDir()\n\n const exists = yield* Effect.tryPromise(() =>\n fs\n .access(sessionsDir)\n .then(() => true)\n .catch(() => false)\n )\n\n if (!exists) {\n return [] as Project[]\n }\n\n const entries = yield* Effect.tryPromise(() => fs.readdir(sessionsDir, { withFileTypes: true }))\n\n const projects = yield* Effect.all(\n entries\n .filter((e) => e.isDirectory())\n .map((entry) =>\n Effect.gen(function* () {\n const projectPath = path.join(sessionsDir, entry.name)\n const files = yield* Effect.tryPromise(() => fs.readdir(projectPath))\n const sessionFiles = files.filter((f) => f.endsWith('.jsonl'))\n\n return {\n name: entry.name,\n path: projectPath,\n sessionCount: sessionFiles.length,\n } satisfies Project\n })\n ),\n { concurrency: 10 }\n )\n\n return projects\n})\n\n// List sessions in a project\nexport const listSessions = (projectName: string) =>\n Effect.gen(function* () {\n const projectPath = path.join(getSessionsDir(), projectName)\n const files = yield* Effect.tryPromise(() => fs.readdir(projectPath))\n const sessionFiles = files.filter((f) => f.endsWith('.jsonl'))\n\n const sessions = yield* Effect.all(\n sessionFiles.map((file) =>\n Effect.gen(function* () {\n const filePath = path.join(projectPath, file)\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, 'utf-8'))\n const lines = content.trim().split('\\n').filter(Boolean)\n const messages = lines.map((line) => JSON.parse(line) as Message)\n\n const sessionId = file.replace('.jsonl', '')\n const firstMessage = messages[0]\n const lastMessage = messages[messages.length - 1]\n\n // Extract title from first user message\n const title = pipe(\n messages,\n A.findFirst((m) => m.type === 'human'),\n O.map((m) => {\n const msg = m.message as { content?: string } | undefined\n const content = msg?.content ?? ''\n return content.slice(0, 50) + (content.length > 50 ? '...' : '')\n }),\n O.getOrElse(() => 'Untitled')\n )\n\n return {\n id: sessionId,\n projectName,\n title,\n messageCount: messages.length,\n createdAt: firstMessage?.timestamp,\n updatedAt: lastMessage?.timestamp,\n } satisfies SessionMeta\n })\n ),\n { concurrency: 10 }\n )\n\n return sessions\n })\n\n// Read session messages\nexport const readSession = (projectName: string, sessionId: string) =>\n Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`)\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, 'utf-8'))\n const lines = content.trim().split('\\n').filter(Boolean)\n return lines.map((line) => JSON.parse(line) as Message)\n })\n\n// Delete a session\nexport const deleteSession = (projectName: string, sessionId: string) =>\n Effect.gen(function* () {\n const sessionsDir = getSessionsDir()\n const filePath = path.join(sessionsDir, projectName, `${sessionId}.jsonl`)\n\n // Create backup directory\n const backupDir = path.join(sessionsDir, projectName, '.bak')\n yield* Effect.tryPromise(() => fs.mkdir(backupDir, { recursive: true }))\n\n // Move to backup\n const backupPath = path.join(backupDir, `${sessionId}.jsonl`)\n yield* Effect.tryPromise(() => fs.rename(filePath, backupPath))\n\n return { success: true, backupPath }\n })\n\n// Rename session by adding title prefix\nexport const renameSession = (projectName: string, sessionId: string, newTitle: string) =>\n Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`)\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, 'utf-8'))\n const lines = content.trim().split('\\n').filter(Boolean)\n\n if (lines.length === 0) {\n return { success: false, error: 'Empty session' }\n }\n\n const messages = lines.map((line) => JSON.parse(line) as Message)\n const firstMsg = messages[0]\n\n // Add title prefix to first message\n if (firstMsg && typeof firstMsg.message === 'object' && firstMsg.message !== null) {\n const msg = firstMsg.message as { content?: string }\n if (msg.content) {\n // Remove existing title prefix if any\n const cleanContent = msg.content.replace(/^\\[.*?\\]\\s*/, '')\n msg.content = `[${newTitle}] ${cleanContent}`\n }\n }\n\n const newContent = messages.map((m) => JSON.stringify(m)).join('\\n') + '\\n'\n yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, 'utf-8'))\n\n return { success: true }\n })\n\n// Delete a message from session\nexport const deleteMessage = (projectName: string, sessionId: string, messageUuid: string) =>\n Effect.gen(function* () {\n const filePath = path.join(getSessionsDir(), projectName, `${sessionId}.jsonl`)\n const content = yield* Effect.tryPromise(() => fs.readFile(filePath, 'utf-8'))\n const lines = content.trim().split('\\n').filter(Boolean)\n const messages = lines.map((line) => JSON.parse(line) as Message)\n\n const targetIndex = messages.findIndex((m) => m.uuid === messageUuid)\n if (targetIndex === -1) {\n return { success: false, error: 'Message not found' }\n }\n\n // Get the parent UUID of deleted message\n const deletedMsg = messages[targetIndex]\n const parentUuid = deletedMsg?.parentUuid\n\n // Update child message to point to deleted message's parent\n const nextMsg = messages[targetIndex + 1]\n if (nextMsg) {\n nextMsg.parentUuid = parentUuid\n }\n\n // Remove the message\n messages.splice(targetIndex, 1)\n\n const newContent = messages.map((m) => JSON.stringify(m)).join('\\n') + '\\n'\n yield* Effect.tryPromise(() => fs.writeFile(filePath, newContent, 'utf-8'))\n\n return { success: true }\n })\n\n// Preview cleanup - find empty and invalid sessions\nexport const previewCleanup = (projectName?: string) =>\n Effect.gen(function* () {\n const projects = yield* listProjects\n const targetProjects = projectName ? projects.filter((p) => p.name === projectName) : projects\n\n const results = yield* Effect.all(\n targetProjects.map((project) =>\n Effect.gen(function* () {\n const sessions = yield* listSessions(project.name)\n const emptySessions = sessions.filter((s) => s.messageCount === 0)\n const invalidSessions = sessions.filter(\n (s) => s.title?.includes('Invalid API key') || s.title?.includes('API key')\n )\n\n return {\n project: project.name,\n emptySessions,\n invalidSessions,\n }\n })\n ),\n { concurrency: 5 }\n )\n\n return results\n })\n\n// Clear sessions (empty and invalid)\nexport const clearSessions = (options: {\n projectName?: string\n clearEmpty?: boolean\n clearInvalid?: boolean\n}) =>\n Effect.gen(function* () {\n const { projectName, clearEmpty = true, clearInvalid = true } = options\n const cleanupPreview = yield* previewCleanup(projectName)\n\n let deletedCount = 0\n\n for (const result of cleanupPreview) {\n const toDelete = [\n ...(clearEmpty ? result.emptySessions : []),\n ...(clearInvalid ? result.invalidSessions : []),\n ]\n\n for (const session of toDelete) {\n yield* deleteSession(result.project, session.id)\n deletedCount++\n }\n }\n\n return { success: true, deletedCount }\n })\n\n// File change info extracted from session\nexport interface FileChange {\n path: string\n action: 'created' | 'modified' | 'deleted'\n timestamp?: string\n messageUuid?: string\n}\n\n// Session file changes summary\nexport interface SessionFilesSummary {\n sessionId: string\n projectName: string\n files: FileChange[]\n totalChanges: number\n}\n\n// Get changed files from a session\nexport const getSessionFiles = (projectName: string, sessionId: string) =>\n Effect.gen(function* () {\n const messages = yield* readSession(projectName, sessionId)\n const fileChanges: FileChange[] = []\n const seenFiles = new Set<string>()\n\n for (const msg of messages) {\n // Check for file-history-snapshot type\n if (msg.type === 'file-history-snapshot') {\n const snapshot = msg as unknown as {\n type: string\n messageId?: string\n snapshot?: {\n trackedFileBackups?: Record<string, unknown>\n timestamp?: string\n }\n }\n\n const backups = snapshot.snapshot?.trackedFileBackups\n if (backups && typeof backups === 'object') {\n for (const filePath of Object.keys(backups)) {\n if (!seenFiles.has(filePath)) {\n seenFiles.add(filePath)\n fileChanges.push({\n path: filePath,\n action: 'modified',\n timestamp: snapshot.snapshot?.timestamp,\n messageUuid: snapshot.messageId ?? msg.uuid,\n })\n }\n }\n }\n }\n\n // Also check tool_use for Write/Edit operations\n if (msg.type === 'assistant' && msg.message) {\n const assistantMsg = msg.message as {\n content?: Array<{ type: string; name?: string; input?: { file_path?: string } }>\n }\n const content = assistantMsg.content\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === 'tool_use' && (block.name === 'Write' || block.name === 'Edit')) {\n const filePath = block.input?.file_path\n if (filePath && !seenFiles.has(filePath)) {\n seenFiles.add(filePath)\n fileChanges.push({\n path: filePath,\n action: block.name === 'Write' ? 'created' : 'modified',\n timestamp: msg.timestamp,\n messageUuid: msg.uuid,\n })\n }\n }\n }\n }\n }\n }\n\n return {\n sessionId,\n projectName,\n files: fileChanges,\n totalChanges: fileChanges.length,\n } satisfies SessionFilesSummary\n })\n\n// Get file changes diff summary for a session\nexport interface FileDiffSummary {\n sessionId: string\n projectName: string\n title: string\n changes: Array<{\n path: string\n action: 'created' | 'modified' | 'deleted'\n hasBackup: boolean\n backupPreview?: string\n }>\n totalFiles: number\n snapshotCount: number\n}\n\nexport const getSessionDiffSummary = (projectName: string, sessionId: string) =>\n Effect.gen(function* () {\n const messages = yield* readSession(projectName, sessionId)\n\n // Extract title\n const title = pipe(\n messages,\n A.findFirst((m) => m.type === 'human'),\n O.map((m) => {\n const msg = m.message as { content?: string } | undefined\n const content = msg?.content ?? ''\n return content.slice(0, 50) + (content.length > 50 ? '...' : '')\n }),\n O.getOrElse(() => 'Untitled')\n )\n\n const changes: FileDiffSummary['changes'] = []\n const seenFiles = new Set<string>()\n let snapshotCount = 0\n\n for (const msg of messages) {\n if (msg.type === 'file-history-snapshot') {\n snapshotCount++\n const snapshot = msg as {\n type: string\n snapshot?: {\n trackedFileBackups?: Record<string, { content?: string }>\n }\n }\n\n const backups = snapshot.snapshot?.trackedFileBackups\n if (backups && typeof backups === 'object') {\n for (const [filePath, backup] of Object.entries(backups)) {\n if (!seenFiles.has(filePath)) {\n seenFiles.add(filePath)\n const backupData = backup as { content?: string } | undefined\n const content = backupData?.content ?? ''\n changes.push({\n path: filePath,\n action: 'modified',\n hasBackup: content.length > 0,\n backupPreview: content.slice(0, 100) + (content.length > 100 ? '...' : ''),\n })\n }\n }\n }\n }\n }\n\n return {\n sessionId,\n projectName,\n title,\n changes,\n totalFiles: changes.length,\n snapshotCount,\n } satisfies FileDiffSummary\n })\n"],"mappings":";;;;;;;AACA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,UAAAA,eAAc;AACvB,SAAS,SAAS;;;ACJlB,SAAS,QAAQ,MAAM,SAAS,GAAG,UAAU,SAAS;AACtD,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,YAAY,QAAQ;AAIb,IAAM,iBAAiB,MAAmB,UAAQ,WAAQ,GAAG,WAAW,UAAU;AAGlF,IAAM,eAAe,OAAO,IAAI,aAAa;AAClD,QAAM,cAAc,eAAe;AAEnC,QAAM,SAAS,OAAO,OAAO;AAAA,IAAW,MAEnC,UAAO,WAAW,EAClB,KAAK,MAAM,IAAI,EACf,MAAM,MAAM,KAAK;AAAA,EACtB;AAEA,MAAI,CAAC,QAAQ;AACX,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAU,OAAO,OAAO,WAAW,MAAS,WAAQ,aAAa,EAAE,eAAe,KAAK,CAAC,CAAC;AAE/F,QAAM,WAAW,OAAO,OAAO;AAAA,IAC7B,QACG,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,EAC7B;AAAA,MAAI,CAAC,UACJ,OAAO,IAAI,aAAa;AACtB,cAAM,cAAmB,UAAK,aAAa,MAAM,IAAI;AACrD,cAAM,QAAQ,OAAO,OAAO,WAAW,MAAS,WAAQ,WAAW,CAAC;AACpE,cAAM,eAAe,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,CAAC;AAE7D,eAAO;AAAA,UACL,MAAM,MAAM;AAAA,UACZ,MAAM;AAAA,UACN,cAAc,aAAa;AAAA,QAC7B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACF,EAAE,aAAa,GAAG;AAAA,EACpB;AAEA,SAAO;AACT,CAAC;AAGM,IAAM,eAAe,CAAC,gBAC3B,OAAO,IAAI,aAAa;AACtB,QAAM,cAAmB,UAAK,eAAe,GAAG,WAAW;AAC3D,QAAM,QAAQ,OAAO,OAAO,WAAW,MAAS,WAAQ,WAAW,CAAC;AACpE,QAAM,eAAe,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,CAAC;AAE7D,QAAM,WAAW,OAAO,OAAO;AAAA,IAC7B,aAAa;AAAA,MAAI,CAAC,SAChB,OAAO,IAAI,aAAa;AACtB,cAAM,WAAgB,UAAK,aAAa,IAAI;AAC5C,cAAM,UAAU,OAAO,OAAO,WAAW,MAAS,YAAS,UAAU,OAAO,CAAC;AAC7E,cAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AACvD,cAAM,WAAW,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,CAAY;AAEhE,cAAM,YAAY,KAAK,QAAQ,UAAU,EAAE;AAC3C,cAAM,eAAe,SAAS,CAAC;AAC/B,cAAM,cAAc,SAAS,SAAS,SAAS,CAAC;AAGhD,cAAM,QAAQ;AAAA,UACZ;AAAA,UACA,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,OAAO;AAAA,UACrC,EAAE,IAAI,CAAC,MAAM;AACX,kBAAM,MAAM,EAAE;AACd,kBAAMC,WAAU,KAAK,WAAW;AAChC,mBAAOA,SAAQ,MAAM,GAAG,EAAE,KAAKA,SAAQ,SAAS,KAAK,QAAQ;AAAA,UAC/D,CAAC;AAAA,UACD,EAAE,UAAU,MAAM,UAAU;AAAA,QAC9B;AAEA,eAAO;AAAA,UACL,IAAI;AAAA,UACJ;AAAA,UACA;AAAA,UACA,cAAc,SAAS;AAAA,UACvB,WAAW,cAAc;AAAA,UACzB,WAAW,aAAa;AAAA,QAC1B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,EAAE,aAAa,GAAG;AAAA,EACpB;AAEA,SAAO;AACT,CAAC;AAGI,IAAM,cAAc,CAAC,aAAqB,cAC/C,OAAO,IAAI,aAAa;AACtB,QAAM,WAAgB,UAAK,eAAe,GAAG,aAAa,GAAG,SAAS,QAAQ;AAC9E,QAAM,UAAU,OAAO,OAAO,WAAW,MAAS,YAAS,UAAU,OAAO,CAAC;AAC7E,QAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AACvD,SAAO,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,CAAY;AACxD,CAAC;AAGI,IAAM,gBAAgB,CAAC,aAAqB,cACjD,OAAO,IAAI,aAAa;AACtB,QAAM,cAAc,eAAe;AACnC,QAAM,WAAgB,UAAK,aAAa,aAAa,GAAG,SAAS,QAAQ;AAGzE,QAAM,YAAiB,UAAK,aAAa,aAAa,MAAM;AAC5D,SAAO,OAAO,WAAW,MAAS,SAAM,WAAW,EAAE,WAAW,KAAK,CAAC,CAAC;AAGvE,QAAM,aAAkB,UAAK,WAAW,GAAG,SAAS,QAAQ;AAC5D,SAAO,OAAO,WAAW,MAAS,UAAO,UAAU,UAAU,CAAC;AAE9D,SAAO,EAAE,SAAS,MAAM,WAAW;AACrC,CAAC;AAGI,IAAM,gBAAgB,CAAC,aAAqB,WAAmB,aACpE,OAAO,IAAI,aAAa;AACtB,QAAM,WAAgB,UAAK,eAAe,GAAG,aAAa,GAAG,SAAS,QAAQ;AAC9E,QAAM,UAAU,OAAO,OAAO,WAAW,MAAS,YAAS,UAAU,OAAO,CAAC;AAC7E,QAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AAEvD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,EAAE,SAAS,OAAO,OAAO,gBAAgB;AAAA,EAClD;AAEA,QAAM,WAAW,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,CAAY;AAChE,QAAM,WAAW,SAAS,CAAC;AAG3B,MAAI,YAAY,OAAO,SAAS,YAAY,YAAY,SAAS,YAAY,MAAM;AACjF,UAAM,MAAM,SAAS;AACrB,QAAI,IAAI,SAAS;AAEf,YAAM,eAAe,IAAI,QAAQ,QAAQ,eAAe,EAAE;AAC1D,UAAI,UAAU,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,aAAa,SAAS,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AACvE,SAAO,OAAO,WAAW,MAAS,aAAU,UAAU,YAAY,OAAO,CAAC;AAE1E,SAAO,EAAE,SAAS,KAAK;AACzB,CAAC;AAGI,IAAM,gBAAgB,CAAC,aAAqB,WAAmB,gBACpE,OAAO,IAAI,aAAa;AACtB,QAAM,WAAgB,UAAK,eAAe,GAAG,aAAa,GAAG,SAAS,QAAQ;AAC9E,QAAM,UAAU,OAAO,OAAO,WAAW,MAAS,YAAS,UAAU,OAAO,CAAC;AAC7E,QAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AACvD,QAAM,WAAW,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,CAAY;AAEhE,QAAM,cAAc,SAAS,UAAU,CAAC,MAAM,EAAE,SAAS,WAAW;AACpE,MAAI,gBAAgB,IAAI;AACtB,WAAO,EAAE,SAAS,OAAO,OAAO,oBAAoB;AAAA,EACtD;AAGA,QAAM,aAAa,SAAS,WAAW;AACvC,QAAM,aAAa,YAAY;AAG/B,QAAM,UAAU,SAAS,cAAc,CAAC;AACxC,MAAI,SAAS;AACX,YAAQ,aAAa;AAAA,EACvB;AAGA,WAAS,OAAO,aAAa,CAAC;AAE9B,QAAM,aAAa,SAAS,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AACvE,SAAO,OAAO,WAAW,MAAS,aAAU,UAAU,YAAY,OAAO,CAAC;AAE1E,SAAO,EAAE,SAAS,KAAK;AACzB,CAAC;AAGI,IAAM,iBAAiB,CAAC,gBAC7B,OAAO,IAAI,aAAa;AACtB,QAAM,WAAW,OAAO;AACxB,QAAM,iBAAiB,cAAc,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,WAAW,IAAI;AAEtF,QAAM,UAAU,OAAO,OAAO;AAAA,IAC5B,eAAe;AAAA,MAAI,CAAC,YAClB,OAAO,IAAI,aAAa;AACtB,cAAM,WAAW,OAAO,aAAa,QAAQ,IAAI;AACjD,cAAM,gBAAgB,SAAS,OAAO,CAAC,MAAM,EAAE,iBAAiB,CAAC;AACjE,cAAM,kBAAkB,SAAS;AAAA,UAC/B,CAAC,MAAM,EAAE,OAAO,SAAS,iBAAiB,KAAK,EAAE,OAAO,SAAS,SAAS;AAAA,QAC5E;AAEA,eAAO;AAAA,UACL,SAAS,QAAQ;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,EAAE,aAAa,EAAE;AAAA,EACnB;AAEA,SAAO;AACT,CAAC;AAGI,IAAM,gBAAgB,CAAC,YAK5B,OAAO,IAAI,aAAa;AACtB,QAAM,EAAE,aAAa,aAAa,MAAM,eAAe,KAAK,IAAI;AAChE,QAAM,iBAAiB,OAAO,eAAe,WAAW;AAExD,MAAI,eAAe;AAEnB,aAAW,UAAU,gBAAgB;AACnC,UAAM,WAAW;AAAA,MACf,GAAI,aAAa,OAAO,gBAAgB,CAAC;AAAA,MACzC,GAAI,eAAe,OAAO,kBAAkB,CAAC;AAAA,IAC/C;AAEA,eAAW,WAAW,UAAU;AAC9B,aAAO,cAAc,OAAO,SAAS,QAAQ,EAAE;AAC/C;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,MAAM,aAAa;AACvC,CAAC;AAmBI,IAAM,kBAAkB,CAAC,aAAqB,cACnD,OAAO,IAAI,aAAa;AACtB,QAAM,WAAW,OAAO,YAAY,aAAa,SAAS;AAC1D,QAAM,cAA4B,CAAC;AACnC,QAAM,YAAY,oBAAI,IAAY;AAElC,aAAW,OAAO,UAAU;AAE1B,QAAI,IAAI,SAAS,yBAAyB;AACxC,YAAM,WAAW;AASjB,YAAM,UAAU,SAAS,UAAU;AACnC,UAAI,WAAW,OAAO,YAAY,UAAU;AAC1C,mBAAW,YAAY,OAAO,KAAK,OAAO,GAAG;AAC3C,cAAI,CAAC,UAAU,IAAI,QAAQ,GAAG;AAC5B,sBAAU,IAAI,QAAQ;AACtB,wBAAY,KAAK;AAAA,cACf,MAAM;AAAA,cACN,QAAQ;AAAA,cACR,WAAW,SAAS,UAAU;AAAA,cAC9B,aAAa,SAAS,aAAa,IAAI;AAAA,YACzC,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,IAAI,SAAS,eAAe,IAAI,SAAS;AAC3C,YAAM,eAAe,IAAI;AAGzB,YAAM,UAAU,aAAa;AAC7B,UAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,mBAAW,SAAS,SAAS;AAC3B,cAAI,MAAM,SAAS,eAAe,MAAM,SAAS,WAAW,MAAM,SAAS,SAAS;AAClF,kBAAM,WAAW,MAAM,OAAO;AAC9B,gBAAI,YAAY,CAAC,UAAU,IAAI,QAAQ,GAAG;AACxC,wBAAU,IAAI,QAAQ;AACtB,0BAAY,KAAK;AAAA,gBACf,MAAM;AAAA,gBACN,QAAQ,MAAM,SAAS,UAAU,YAAY;AAAA,gBAC7C,WAAW,IAAI;AAAA,gBACf,aAAa,IAAI;AAAA,cACnB,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,cAAc,YAAY;AAAA,EAC5B;AACF,CAAC;AAiBI,IAAM,wBAAwB,CAAC,aAAqB,cACzD,OAAO,IAAI,aAAa;AACtB,QAAM,WAAW,OAAO,YAAY,aAAa,SAAS;AAG1D,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,OAAO;AAAA,IACrC,EAAE,IAAI,CAAC,MAAM;AACX,YAAM,MAAM,EAAE;AACd,YAAM,UAAU,KAAK,WAAW;AAChC,aAAO,QAAQ,MAAM,GAAG,EAAE,KAAK,QAAQ,SAAS,KAAK,QAAQ;AAAA,IAC/D,CAAC;AAAA,IACD,EAAE,UAAU,MAAM,UAAU;AAAA,EAC9B;AAEA,QAAM,UAAsC,CAAC;AAC7C,QAAM,YAAY,oBAAI,IAAY;AAClC,MAAI,gBAAgB;AAEpB,aAAW,OAAO,UAAU;AAC1B,QAAI,IAAI,SAAS,yBAAyB;AACxC;AACA,YAAM,WAAW;AAOjB,YAAM,UAAU,SAAS,UAAU;AACnC,UAAI,WAAW,OAAO,YAAY,UAAU;AAC1C,mBAAW,CAAC,UAAU,MAAM,KAAK,OAAO,QAAQ,OAAO,GAAG;AACxD,cAAI,CAAC,UAAU,IAAI,QAAQ,GAAG;AAC5B,sBAAU,IAAI,QAAQ;AACtB,kBAAM,aAAa;AACnB,kBAAM,UAAU,YAAY,WAAW;AACvC,oBAAQ,KAAK;AAAA,cACX,MAAM;AAAA,cACN,QAAQ;AAAA,cACR,WAAW,QAAQ,SAAS;AAAA,cAC5B,eAAe,QAAQ,MAAM,GAAG,GAAG,KAAK,QAAQ,SAAS,MAAM,QAAQ;AAAA,YACzE,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,QAAQ;AAAA,IACpB;AAAA,EACF;AACF,CAAC;;;ADlYH,IAAM,SAAS,IAAI,UAAU;AAAA,EAC3B,MAAM;AAAA,EACN,SAAS;AACX,CAAC;AAGD,OAAO,KAAK,iBAAiB,qDAAqD,CAAC,GAAG,YAAY;AAChG,QAAM,SAAS,MAAMC,QAAO,WAAmB,YAAY;AAC3D,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,EACnE;AACF,CAAC;AAGD,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,4DAA4D;AAAA,EAChG;AAAA,EACA,OAAO,EAAE,aAAa,MAAM;AAC1B,UAAM,SAAS,MAAMA,QAAO,WAAmB,aAAa,YAAY,CAAC;AACzE,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,IACvD,YAAY,EAAE,OAAO,EAAE,SAAS,sCAAsC;AAAA,IACtE,WAAW,EAAE,OAAO,EAAE,SAAS,4BAA4B;AAAA,EAC7D;AAAA,EACA,OAAO,EAAE,cAAc,YAAY,UAAU,MAAM;AACjD,UAAM,SAAS,MAAMA,QAAO;AAAA,MAClB,cAAc,cAAc,YAAY,SAAS;AAAA,IAC3D;AACA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,IACvD,YAAY,EAAE,OAAO,EAAE,SAAS,sBAAsB;AAAA,EACxD;AAAA,EACA,OAAO,EAAE,cAAc,WAAW,MAAM;AACtC,UAAM,SAAS,MAAMA,QAAO,WAAmB,cAAc,cAAc,UAAU,CAAC;AACtF,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,IACvD,YAAY,EAAE,OAAO,EAAE,SAAS,YAAY;AAAA,IAC5C,cAAc,EAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,EACnE;AAAA,EACA,OAAO,EAAE,cAAc,YAAY,aAAa,MAAM;AACpD,UAAM,SAAS,MAAMA,QAAO;AAAA,MAClB,cAAc,cAAc,YAAY,YAAY;AAAA,IAC9D;AACA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,EACjF;AAAA,EACA,OAAO,EAAE,aAAa,MAAM;AAC1B,UAAM,SAAS,MAAMA,QAAO,WAAmB,eAAe,YAAY,CAAC;AAC3E,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,IAC/E,aAAa,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,sCAAsC;AAAA,IACtF,eAAe,EACZ,QAAQ,EACR,QAAQ,IAAI,EACZ,SAAS,gDAAgD;AAAA,EAC9D;AAAA,EACA,OAAO,EAAE,cAAc,aAAa,cAAc,MAAM;AACtD,UAAM,SAAS,MAAMA,QAAO;AAAA,MAClB,cAAc;AAAA,QACpB,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AACA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,IACvD,YAAY,EAAE,OAAO,EAAE,SAAS,YAAY;AAAA,EAC9C;AAAA,EACA,OAAO,EAAE,cAAc,WAAW,MAAM;AACtC,UAAM,SAAS,MAAMA,QAAO,WAAmB,gBAAgB,cAAc,UAAU,CAAC;AACxF,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,cAAc,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,IACvD,YAAY,EAAE,OAAO,EAAE,SAAS,YAAY;AAAA,EAC9C;AAAA,EACA,OAAO,EAAE,cAAc,WAAW,MAAM;AACtC,UAAM,SAAS,MAAMA,QAAO,WAAmB,sBAAsB,cAAc,UAAU,CAAC;AAC9F,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,IACnE;AAAA,EACF;AACF;AAGA,IAAI,oBAAuE;AAE3E,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,IACE,MAAM,EAAE,OAAO,EAAE,QAAQ,IAAI,EAAE,SAAS,+CAA+C;AAAA,IACvF,cAAc,EACX,QAAQ,EACR,QAAQ,IAAI,EACZ,SAAS,uDAAuD;AAAA,IACnE,SAAS,EACN,QAAQ,EACR,QAAQ,KAAK,EACb,SAAS,wDAAwD;AAAA,EACtE;AAAA,EACA,OAAO,EAAE,MAAM,cAAc,QAAQ,MAAM;AACzC,QAAI;AACF,UAAI,mBAAmB;AACrB,YAAI,SAAS;AACX,gBAAM,cAAc,iBAAiB;AACrC,8BAAoB;AAAA,QACtB,OAAO;AACL,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK;AAAA,kBACT;AAAA,oBACE,SAAS;AAAA,oBACT,SAAS;AAAA,oBACT,KAAK,oBAAoB,IAAI;AAAA,kBAC/B;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,0BAAoB,MAAM,eAAe,MAAM,YAAY;AAE3D,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,KAAK;AAAA,cACT;AAAA,gBACE,SAAS;AAAA,gBACT,SAAS;AAAA,gBACT,KAAK,oBAAoB,IAAI;AAAA,gBAC7B,KAAK,QAAQ;AAAA,cACf;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,KAAK;AAAA,cACT;AAAA,gBACE,SAAS;AAAA,gBACT,OAAO,OAAO,KAAK;AAAA,cACrB;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAGA,OAAO,KAAK,YAAY,2BAA2B,CAAC,GAAG,YAAY;AACjE,MAAI,mBAAmB;AACrB,UAAM,OAAO,kBAAkB;AAE/B,QAAI;AACF,YAAM,MAAM,oBAAoB,IAAI,iBAAiB,EAAE,QAAQ,OAAO,CAAC;AAAA,IACzE,QAAQ;AAAA,IAER;AAEA,UAAM,cAAc,iBAAiB;AACrC,wBAAoB;AACpB,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,UAAU,EAAE,SAAS,MAAM,SAAS,+BAA+B,GAAG,MAAM,CAAC;AAAA,QAC1F;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU,EAAE,SAAS,MAAM,SAAS,0BAA0B,GAAG,MAAM,CAAC;AAAA,MACrF;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAGD,eAAe,OAAO;AACpB,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK,EAAE,MAAM,QAAQ,KAAK;","names":["Effect","content","Effect"]}
|
package/dist/server.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-font-weight:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-700:oklch(50.5% .213 27.518);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-white:#fff;--spacing:.25rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-gh-bg:#0d1117;--color-gh-bg-secondary:#161b22;--color-gh-border:#30363d;--color-gh-border-subtle:#21262d;--color-gh-text:#c9d1d9;--color-gh-text-secondary:#8b949e;--color-gh-accent:#1f6feb;--color-gh-green:#238636;--color-gh-red:#f85149}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.fixed{position:fixed}.relative{position:relative}.right-4{right:calc(var(--spacing)*4)}.bottom-4{bottom:calc(var(--spacing)*4)}.z-50{z-index:50}.mx-auto{margin-inline:auto}.mt-1{margin-top:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-\[calc\(100vh-120px\)\]{height:calc(100vh - 120px)}.min-h-screen{min-height:100vh}.w-3{width:calc(var(--spacing)*3)}.w-full{width:100%}.max-w-7xl{max-width:var(--container-7xl)}.min-w-0{min-width:calc(var(--spacing)*0)}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.cursor-pointer{cursor:pointer}.grid-cols-\[350px_1fr\]{grid-template-columns:350px 1fr}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:calc(var(--spacing)*.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-3{border-left-style:var(--tw-border-style);border-left-width:3px}.border-none{--tw-border-style:none;border-style:none}.border-gh-border{border-color:var(--color-gh-border)}.border-gh-border-subtle{border-color:var(--color-gh-border-subtle)}.border-gh-red{border-color:var(--color-gh-red)}.border-l-gh-accent{border-left-color:var(--color-gh-accent)}.border-l-gh-green{border-left-color:var(--color-gh-green)}.border-l-purple-500{border-left-color:var(--color-purple-500)}.bg-gh-accent{background-color:var(--color-gh-accent)}.bg-gh-accent\/10{background-color:#1f6feb1a}@supports (color:color-mix(in lab,red,red)){.bg-gh-accent\/10{background-color:color-mix(in oklab,var(--color-gh-accent)10%,transparent)}}.bg-gh-accent\/15{background-color:#1f6feb26}@supports (color:color-mix(in lab,red,red)){.bg-gh-accent\/15{background-color:color-mix(in oklab,var(--color-gh-accent)15%,transparent)}}.bg-gh-accent\/20{background-color:#1f6feb33}@supports (color:color-mix(in lab,red,red)){.bg-gh-accent\/20{background-color:color-mix(in oklab,var(--color-gh-accent)20%,transparent)}}.bg-gh-bg{background-color:var(--color-gh-bg)}.bg-gh-bg-secondary{background-color:var(--color-gh-bg-secondary)}.bg-gh-border{background-color:var(--color-gh-border)}.bg-gh-border-subtle{background-color:var(--color-gh-border-subtle)}.bg-gh-green{background-color:var(--color-gh-green)}.bg-gh-green\/15{background-color:#23863626}@supports (color:color-mix(in lab,red,red)){.bg-gh-green\/15{background-color:color-mix(in oklab,var(--color-gh-green)15%,transparent)}}.bg-gh-red{background-color:var(--color-gh-red)}.bg-purple-500\/15{background-color:#ac4bff26}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/15{background-color:color-mix(in oklab,var(--color-purple-500)15%,transparent)}}.bg-transparent{background-color:#0000}.p-1{padding:calc(var(--spacing)*1)}.p-4{padding:calc(var(--spacing)*4)}.p-8{padding:calc(var(--spacing)*8)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-px{padding-block:1px}.pr-2{padding-right:calc(var(--spacing)*2)}.pl-8{padding-left:calc(var(--spacing)*8)}.pl-\[calc\(2rem-3px\)\]{padding-left:calc(2rem - 3px)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.break-words{overflow-wrap:break-word}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-gh-text{color:var(--color-gh-text)}.text-gh-text-secondary{color:var(--color-gh-text-secondary)}.text-gh-text-secondary\/70{color:#8b949eb3}@supports (color:color-mix(in lab,red,red)){.text-gh-text-secondary\/70{color:color-mix(in oklab,var(--color-gh-text-secondary)70%,transparent)}}.text-purple-400{color:var(--color-purple-400)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.opacity-0{opacity:0}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.group-hover\:hidden:is(:where(.group):hover *){display:none}.group-hover\:inline:is(:where(.group):hover *){display:inline}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:border-gh-text-secondary:hover{border-color:var(--color-gh-text-secondary)}.hover\:bg-gh-border:hover{background-color:var(--color-gh-border)}.hover\:bg-gh-border-subtle:hover{background-color:var(--color-gh-border-subtle)}.hover\:bg-gh-red\/20:hover{background-color:#f8514933}@supports (color:color-mix(in lab,red,red)){.hover\:bg-gh-red\/20:hover{background-color:color-mix(in oklab,var(--color-gh-red)20%,transparent)}}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var Oe=Object.defineProperty;var de=t=>{throw TypeError(t)};var De=(t,e,r)=>e in t?Oe(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var ce=(t,e,r)=>De(t,typeof e!="symbol"?e+"":e,r),Z=(t,e,r)=>e.has(t)||de("Cannot "+r);var s=(t,e,r)=>(Z(t,e,"read from private field"),r?r.call(t):e.get(t)),h=(t,e,r)=>e.has(t)?de("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r),i=(t,e,r,a)=>(Z(t,e,"write to private field"),a?a.call(t,r):e.set(t,r),r),p=(t,e,r)=>(Z(t,e,"access private method"),r);import{ab as Fe,F as ye,V as Ee,ac as ke,L as Ce,ad as _e,a4 as Te,e as v,h as T,ae as P,f as Le,g as be,C as he,H as Me,b as C,af as W,p as ee,a as x,ag as J,ah as H,ai as pe,aj as Ie,ak as re,I as we,m as Pe,T as Ve,d as te,k as Y,al as Be,j as He,am as ge,an as qe,E as xe,ao as Ye,ap as je,aq as Ue,ar as We,o as se,as as
|
|
2
|
-
`).some(m=>m.startsWith("https://svelte.dev/e/")))throw l;return l!==ie&&console.warn("Failed to hydrate: ",l),e.recover===!1&&Ze(),ne(),et(r),
|
|
1
|
+
var Oe=Object.defineProperty;var de=t=>{throw TypeError(t)};var De=(t,e,r)=>e in t?Oe(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var ce=(t,e,r)=>De(t,typeof e!="symbol"?e+"":e,r),Z=(t,e,r)=>e.has(t)||de("Cannot "+r);var s=(t,e,r)=>(Z(t,e,"read from private field"),r?r.call(t):e.get(t)),h=(t,e,r)=>e.has(t)?de("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r),i=(t,e,r,a)=>(Z(t,e,"write to private field"),a?a.call(t,r):e.set(t,r),r),p=(t,e,r)=>(Z(t,e,"access private method"),r);import{ab as Fe,F as ye,V as Ee,ac as ke,L as Ce,ad as _e,a4 as Te,e as v,h as T,ae as P,f as Le,g as be,C as he,H as Me,b as C,af as W,p as ee,a as x,ag as J,ah as H,ai as pe,aj as Ie,ak as re,I as we,m as Pe,T as Ve,d as te,k as Y,al as Be,j as He,am as ge,an as qe,E as xe,ao as Ye,ap as je,aq as Ue,ar as We,o as se,as as ze,at as Xe,au as $e,av as Ge,aw as Je,ax as ne,ay as Ke,q as Qe,az as ie,l as z,aA as Ze,a2 as et,X as tt,aB as rt,t as st,S as nt,aC as it,z as at}from"./DUfrtY0h.js";function ot(t){let e=0,r=Ee(0),a;return()=>{Fe()&&(ye(r),ke(()=>(e===0&&(a=Ce(()=>t(()=>_e(r)))),e+=1,()=>{Te(()=>{e-=1,e===0&&(a==null||a(),a=void 0,_e(r))})})))}}var lt=xe|Ye|je;function ft(t,e,r){new ht(t,e,r)}var y,g,j,b,L,w,E,c,N,A,O,M,D,I,F,K,f,Ne,Re,ae,$,G,oe;class ht{constructor(e,r,a){h(this,f);ce(this,"parent");h(this,y,!1);h(this,g);h(this,j,T?v:null);h(this,b);h(this,L);h(this,w);h(this,E,null);h(this,c,null);h(this,N,null);h(this,A,null);h(this,O,null);h(this,M,0);h(this,D,0);h(this,I,!1);h(this,F,null);h(this,K,ot(()=>(i(this,F,Ee(s(this,M))),()=>{i(this,F,null)})));i(this,g,e),i(this,b,r),i(this,L,a),this.parent=P.b,i(this,y,!!s(this,b).pending),i(this,w,Le(()=>{if(P.b=this,T){const n=s(this,j);be(),n.nodeType===he&&n.data===Me?p(this,f,Re).call(this):p(this,f,Ne).call(this)}else{var o=p(this,f,ae).call(this);try{i(this,E,C(()=>a(o)))}catch(n){this.error(n)}s(this,D)>0?p(this,f,G).call(this):i(this,y,!1)}return()=>{var n;(n=s(this,O))==null||n.remove()}},lt)),T&&i(this,g,v)}is_pending(){return s(this,y)||!!this.parent&&this.parent.is_pending()}has_pending_snippet(){return!!s(this,b).pending}update_pending_count(e){p(this,f,oe).call(this,e),i(this,M,s(this,M)+e),s(this,F)&&Ve(s(this,F),s(this,M))}get_effect_pending(){return s(this,K).call(this),ye(s(this,F))}error(e){var r=s(this,b).onerror;let a=s(this,b).failed;if(s(this,I)||!r&&!a)throw e;s(this,E)&&(te(s(this,E)),i(this,E,null)),s(this,c)&&(te(s(this,c)),i(this,c,null)),s(this,N)&&(te(s(this,N)),i(this,N,null)),T&&(Y(s(this,j)),Be(),Y(He()));var o=!1,n=!1;const l=()=>{if(o){Ue();return}o=!0,n&&qe(),W.ensure(),i(this,M,0),s(this,N)!==null&&ee(s(this,N),()=>{i(this,N,null)}),i(this,y,this.has_pending_snippet()),i(this,E,p(this,f,$).call(this,()=>(i(this,I,!1),C(()=>s(this,L).call(this,s(this,g)))))),s(this,D)>0?p(this,f,G).call(this):i(this,y,!1)};var m=re;try{H(null),n=!0,r==null||r(e,l),n=!1}catch(_){ge(_,s(this,w)&&s(this,w).parent)}finally{H(m)}a&&Te(()=>{i(this,N,p(this,f,$).call(this,()=>{W.ensure(),i(this,I,!0);try{return C(()=>{a(s(this,g),()=>e,()=>l)})}catch(_){return ge(_,s(this,w).parent),null}finally{i(this,I,!1)}}))})}}y=new WeakMap,g=new WeakMap,j=new WeakMap,b=new WeakMap,L=new WeakMap,w=new WeakMap,E=new WeakMap,c=new WeakMap,N=new WeakMap,A=new WeakMap,O=new WeakMap,M=new WeakMap,D=new WeakMap,I=new WeakMap,F=new WeakMap,K=new WeakMap,f=new WeakSet,Ne=function(){try{i(this,E,C(()=>s(this,L).call(this,s(this,g))))}catch(e){this.error(e)}i(this,y,!1)},Re=function(){const e=s(this,b).pending;e&&(i(this,c,C(()=>e(s(this,g)))),W.enqueue(()=>{var r=p(this,f,ae).call(this);i(this,E,p(this,f,$).call(this,()=>(W.ensure(),C(()=>s(this,L).call(this,r))))),s(this,D)>0?p(this,f,G).call(this):(ee(s(this,c),()=>{i(this,c,null)}),i(this,y,!1))}))},ae=function(){var e=s(this,g);return s(this,y)&&(i(this,O,x()),s(this,g).before(s(this,O)),e=s(this,O)),e},$=function(e){var r=P,a=re,o=we;J(s(this,w)),H(s(this,w)),pe(s(this,w).ctx);try{return e()}catch(n){return Ie(n),null}finally{J(r),H(a),pe(o)}},G=function(){const e=s(this,b).pending;s(this,E)!==null&&(i(this,A,document.createDocumentFragment()),s(this,A).append(s(this,O)),Pe(s(this,E),s(this,A))),s(this,c)===null&&i(this,c,C(()=>e(s(this,g))))},oe=function(e){var r;if(!this.has_pending_snippet()){this.parent&&p(r=this.parent,f,oe).call(r,e);return}i(this,D,s(this,D)+e),s(this,D)===0&&(i(this,y,!1),s(this,c)&&ee(s(this,c),()=>{i(this,c,null)}),s(this,A)&&(s(this,g).before(s(this,A)),i(this,A,null)))};const ut=["touchstart","touchmove"];function dt(t){return ut.includes(t)}const Se=new Set,le=new Set;function mt(t){for(var e=0;e<t.length;e++)Se.add(t[e]);for(var r of le)r(t)}let ve=null;function X(t){var ue;var e=this,r=e.ownerDocument,a=t.type,o=((ue=t.composedPath)==null?void 0:ue.call(t))||[],n=o[0]||t.target;ve=t;var l=0,m=ve===t&&t.__root;if(m){var _=o.indexOf(m);if(_!==-1&&(e===document||e===window)){t.__root=e;return}var V=o.indexOf(e);if(V===-1)return;_<=V&&(l=_)}if(n=o[l]||t.target,n!==e){We(t,"currentTarget",{configurable:!0,get(){return n||r}});var Q=re,R=P;H(null),J(null);try{for(var u,d=[];n!==null;){var S=n.assignedSlot||n.parentNode||n.host||null;try{var q=n["__"+a];q!=null&&(!n.disabled||t.target===n)&&q.call(n,t)}catch(U){u?d.push(U):u=U}if(t.cancelBubble||S===e||S===null)break;n=S}if(u){for(let U of d)queueMicrotask(()=>{throw U});throw u}}finally{t.__root=e,delete t.currentTarget,H(Q),J(R)}}}function ct(t){var e=document.createElement("template");return e.innerHTML=t.replaceAll("<!>","<!---->"),e.content}function k(t,e){var r=P;r.nodes===null&&(r.nodes={start:t,end:e,a:null,t:null})}function yt(t,e){var r=(e&Xe)!==0,a=(e&$e)!==0,o,n=!t.startsWith("<!>");return()=>{if(T)return k(v,null),v;o===void 0&&(o=ct(n?t:"<!>"+t),r||(o=se(o)));var l=a||ze?document.importNode(o,!0):o.cloneNode(!0);if(r){var m=se(l),_=l.lastChild;k(m,_)}else k(l,l);return l}}function Et(t=""){if(!T){var e=x(t+"");return k(e,e),e}var r=v;return r.nodeType!==Je&&(r.before(r=x()),Y(r)),k(r,r),r}function Tt(){if(T)return k(v,null),v;var t=document.createDocumentFragment(),e=document.createComment(""),r=x();return t.append(e,r),k(e,r),t}function bt(t,e){if(T){var r=P;((r.f&Ge)===0||r.nodes.end===null)&&(r.nodes.end=v),be();return}t!==null&&t.before(e)}function wt(t,e){var r=e==null?"":typeof e=="object"?e+"":e;r!==(t.__t??(t.__t=t.nodeValue))&&(t.__t=r,t.nodeValue=r+"")}function _t(t,e){return Ae(t,e)}function Nt(t,e){ne(),e.intro=e.intro??!1;const r=e.target,a=T,o=v;try{for(var n=se(r);n&&(n.nodeType!==he||n.data!==Ke);)n=Qe(n);if(!n)throw ie;z(!0),Y(n);const l=Ae(t,{...e,anchor:n});return z(!1),l}catch(l){if(l instanceof Error&&l.message.split(`
|
|
2
|
+
`).some(m=>m.startsWith("https://svelte.dev/e/")))throw l;return l!==ie&&console.warn("Failed to hydrate: ",l),e.recover===!1&&Ze(),ne(),et(r),z(!1),_t(t,e)}finally{z(a),Y(o)}}const B=new Map;function Ae(t,{target:e,anchor:r,props:a={},events:o,context:n,intro:l=!0}){ne();var m=new Set,_=R=>{for(var u=0;u<R.length;u++){var d=R[u];if(!m.has(d)){m.add(d);var S=dt(d);e.addEventListener(d,X,{passive:S});var q=B.get(d);q===void 0?(document.addEventListener(d,X,{passive:S}),B.set(d,1)):B.set(d,q+1)}}};_(tt(Se)),le.add(_);var V=void 0,Q=rt(()=>{var R=r??e.appendChild(x());return ft(R,{pending:()=>{}},u=>{if(n){st({});var d=we;d.c=n}if(o&&(a.$$events=o),T&&k(u,null),V=t(u,a)||{},T&&(P.nodes.end=v,v===null||v.nodeType!==he||v.data!==nt))throw it(),ie;n&&at()}),()=>{var S;for(var u of m){e.removeEventListener(u,X);var d=B.get(u);--d===0?(document.removeEventListener(u,X),B.delete(u)):B.set(u,d)}le.delete(_),R!==r&&((S=R.parentNode)==null||S.removeChild(R))}});return fe.set(V,Q),V}let fe=new WeakMap;function Rt(t,e){const r=fe.get(t);return r?(fe.delete(t),r(e)):Promise.resolve()}const pt="5";var me;typeof window<"u"&&((me=window.__svelte??(window.__svelte={})).v??(me.v=new Set)).add(pt);export{bt as a,Tt as c,mt as d,yt as f,Nt as h,_t as m,wt as s,Et as t,Rt as u};
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const t="/api",s=async e=>{const o=await fetch(`${t}${e}`);if(!o.ok)throw new Error(await o.text());return o.json()},c=async(e,o)=>{const n=await fetch(`${t}${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok)throw new Error(await n.text());return n.json()},a=async e=>{const o=await fetch(`${t}${e}`,{method:"DELETE"});if(!o.ok)throw new Error(await o.text());return o.json()},i=async(e,o)=>{const n=await fetch(`${t}${e}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok)throw new Error(await n.text());return n.json()},p=()=>s("/projects"),d=e=>s(`/sessions?project=${encodeURIComponent(e)}`),$=(e,o)=>s(`/session?project=${encodeURIComponent(e)}&id=${encodeURIComponent(o)}`),m=(e,o)=>a(`/session?project=${encodeURIComponent(e)}&id=${encodeURIComponent(o)}`),w=(e,o,n)=>c("/session/rename",{project:e,id:o,title:n}),
|
|
1
|
+
const t="/api",s=async e=>{const o=await fetch(`${t}${e}`);if(!o.ok)throw new Error(await o.text());return o.json()},c=async(e,o)=>{const n=await fetch(`${t}${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok)throw new Error(await n.text());return n.json()},a=async e=>{const o=await fetch(`${t}${e}`,{method:"DELETE"});if(!o.ok)throw new Error(await o.text());return o.json()},i=async(e,o)=>{const n=await fetch(`${t}${e}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok)throw new Error(await n.text());return n.json()},p=()=>s("/projects"),d=e=>s(`/sessions?project=${encodeURIComponent(e)}`),$=(e,o)=>s(`/session?project=${encodeURIComponent(e)}&id=${encodeURIComponent(o)}`),m=(e,o)=>a(`/session?project=${encodeURIComponent(e)}&id=${encodeURIComponent(o)}`),w=(e,o,n)=>c("/session/rename",{project:e,id:o,title:n}),h=(e,o,n)=>a(`/message?project=${encodeURIComponent(e)}&session=${encodeURIComponent(o)}&uuid=${encodeURIComponent(n)}`),u=(e,o,n,r)=>i(`/message?project=${encodeURIComponent(e)}&session=${encodeURIComponent(o)}&uuid=${encodeURIComponent(n)}`,{customTitle:r}),C=e=>s("/cleanup"),j=e=>c("/cleanup",e),l=()=>s("/version"),R=()=>c("/shutdown",{});export{d as a,$ as b,j as c,h as d,m as e,l as g,p as l,C as p,w as r,R as s,u};
|
|
Binary file
|
|
Binary file
|