MCPcopy Create free account
hub / github.com/coder/mux / readTranscriptFromPaths

Function readTranscriptFromPaths

src/node/orpc/router.ts:4452–4503  ·  view source on GitHub ↗
(params: {
            workspaceId: string;
            chatPath?: string;
            /** Sealed pre-boundary history (chat-archive.jsonl) for live sessions. */
            chatArchivePath?: string;
            partialPath?: string;
            logLabel: string;
          })

Source from the content-addressed store, hash-verified

4450 }
4451
4452 const readTranscriptFromPaths = async (params: {
4453 workspaceId: string;
4454 chatPath?: string;
4455 /** Sealed pre-boundary history (chat-archive.jsonl) for live sessions. */
4456 chatArchivePath?: string;
4457 partialPath?: string;
4458 logLabel: string;
4459 }): Promise<MuxMessage[]> => {
4460 const workspaceSessionDir = context.config.getSessionDir(params.workspaceId);
4461
4462 // Defense-in-depth: refuse path traversal from a corrupted index file.
4463 if (params.chatPath && !isPathInsideDir(workspaceSessionDir, params.chatPath)) {
4464 throw new Error("Refusing to read transcript outside workspace session dir");
4465 }
4466 if (
4467 params.chatArchivePath &&
4468 !isPathInsideDir(workspaceSessionDir, params.chatArchivePath)
4469 ) {
4470 throw new Error("Refusing to read transcript archive outside workspace session dir");
4471 }
4472 if (params.partialPath && !isPathInsideDir(workspaceSessionDir, params.partialPath)) {
4473 throw new Error("Refusing to read partial outside workspace session dir");
4474 }
4475
4476 const partial = params.partialPath
4477 ? await readPartialJsonBestEffort(params.partialPath)
4478 : null;
4479 // Live sessions may have rotated sealed history into chat-archive.jsonl
4480 // (older rows), which precedes chat.jsonl (active epoch).
4481 const archivedMessages = params.chatArchivePath
4482 ? await readChatJsonlAllowMissing({
4483 chatPath: params.chatArchivePath,
4484 logLabel: `${params.logLabel} (archive)`,
4485 })
4486 : null;
4487 const messages = params.chatPath
4488 ? await readChatJsonlAllowMissing({
4489 chatPath: params.chatPath,
4490 logLabel: params.logLabel,
4491 })
4492 : null;
4493
4494 // If we only archived partial.json (e.g. interrupted stream), still allow viewing.
4495 if (!messages && !archivedMessages && !partial) {
4496 throw new Error(`Transcript not found (missing ${params.logLabel})`);
4497 }
4498
4499 return mergePartialIntoHistory(
4500 [...(archivedMessages ?? []), ...(messages ?? [])],
4501 partial
4502 );
4503 };
4504
4505 let resolved: {
4506 workspaceId: string;

Callers 1

routerFunction · 0.85

Calls 5

isPathInsideDirFunction · 0.90
mergePartialIntoHistoryFunction · 0.85
getSessionDirMethod · 0.65

Tested by

no test coverage detected