mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 06:57:10 +00:00
refactor(archive): consolidate export ownership
This commit is contained in:
parent
5b6fce1a4d
commit
6bdd9e5972
10 changed files with 28 additions and 43 deletions
|
|
@ -1,7 +0,0 @@
|
|||
export function yamlFrontmatterString(value: string): string {
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
|
||||
export function yamlFrontmatterInlineList(values: readonly string[]): string {
|
||||
return `[${values.map(yamlFrontmatterString).join(", ")}]`;
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ import { fromMarkdown } from "mdast-util-from-markdown";
|
|||
import { toMarkdown } from "mdast-util-to-markdown";
|
||||
import { visit } from "unist-util-visit";
|
||||
|
||||
import { yamlFrontmatterInlineList, yamlFrontmatterString } from "../markdown/frontmatter";
|
||||
import { parseFileHref } from "../vault/file-hrefs";
|
||||
import { isFilesystemAbsolutePath, isVaultConfigPath, normalizeFilePath, vaultRelativePath } from "../vault/paths";
|
||||
import type { Thread } from "./model";
|
||||
|
|
@ -16,9 +15,7 @@ interface MarkdownSourceReplacement {
|
|||
value: string;
|
||||
}
|
||||
|
||||
export interface ArchiveExportSettings {
|
||||
archiveExportFolderTemplate: string;
|
||||
archiveExportFilenameTemplate: string;
|
||||
export interface ArchiveMarkdownOptions {
|
||||
archiveExportTags?: string;
|
||||
vaultPath?: string;
|
||||
vaultConfigDir?: string;
|
||||
|
|
@ -28,13 +25,9 @@ export interface ArchiveThreadInput extends Thread {
|
|||
transcriptEntries: readonly ThreadTranscriptEntry[];
|
||||
}
|
||||
|
||||
export function archivedThreadMarkdown(
|
||||
thread: ArchiveThreadInput,
|
||||
exportedAt = new Date(),
|
||||
settings?: Partial<ArchiveExportSettings>,
|
||||
): string {
|
||||
export function archivedThreadMarkdown(thread: ArchiveThreadInput, exportedAt = new Date(), settings: ArchiveMarkdownOptions = {}): string {
|
||||
const title = threadArchiveTitle(thread);
|
||||
const tags = normalizedArchiveTags(settings?.archiveExportTags ?? "");
|
||||
const tags = normalizedArchiveTags(settings.archiveExportTags ?? "");
|
||||
const frontmatter = [
|
||||
"---",
|
||||
`title: ${yamlFrontmatterString(title)}`,
|
||||
|
|
@ -44,7 +37,7 @@ export function archivedThreadMarkdown(
|
|||
"---",
|
||||
].join("\n");
|
||||
const body = `${trimTrailingBlankLines([`# ${title}`, "", ...transcriptMarkdownLines(thread.transcriptEntries)]).join("\n")}\n`;
|
||||
const normalizedBody = settings?.vaultPath ? normalizeExportedMarkdownLinks(body, settings.vaultPath, settings.vaultConfigDir) : body;
|
||||
const normalizedBody = settings.vaultPath ? normalizeExportedMarkdownLinks(body, settings.vaultPath, settings.vaultConfigDir) : body;
|
||||
return `${frontmatter}\n\n${normalizedBody}`;
|
||||
}
|
||||
|
||||
|
|
@ -198,3 +191,11 @@ function trimTrailingBlankLines(lines: string[]): string[] {
|
|||
while (result[result.length - 1] === "") result.pop();
|
||||
return result;
|
||||
}
|
||||
|
||||
function yamlFrontmatterString(value: string): string {
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
|
||||
function yamlFrontmatterInlineList(values: readonly string[]): string {
|
||||
return `[${values.map(yamlFrontmatterString).join(", ")}]`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,9 @@ import type { ObservedResultListener } from "../../../app-server/query/observed-
|
|||
import type { ModelMetadata } from "../../../domain/catalog/metadata";
|
||||
import type { SendShortcut } from "../../../domain/input/send-shortcut";
|
||||
import type { SharedServerMetadata, SharedServerMetadataResource } from "../../../domain/server/metadata";
|
||||
import type { ArchiveExportSettings } from "../../../domain/threads/archive-markdown";
|
||||
import type { KeyedOperationQueue } from "../../../shared/runtime/keyed-operation-queue";
|
||||
import type { ThreadCatalogEventSink, ThreadCatalogPaginatedActiveReader } from "../../threads/catalog/thread-catalog";
|
||||
import type { ArchiveExportDestination } from "../../threads/workflows/archive-export";
|
||||
import type { ArchiveExportDestination, ArchiveExportSettings } from "../../threads/workflows/archive-export";
|
||||
import type { ThreadTitleTransport } from "../../threads/workflows/ports";
|
||||
import type { ThreadNameMutationCoordinator } from "../../threads/workflows/thread-name-mutation-coordinator";
|
||||
import type { TurnDiffViewState } from "../../turn-diff/model";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, ItemView, type ViewStateResult, type WorkspaceLeaf } from "obsidian";
|
||||
|
||||
import { VIEW_TYPE_CODEX_PANEL } from "../../../constants";
|
||||
import { createObsidianArchiveExportDestination } from "../../threads/obsidian/archive-export-destination.obsidian";
|
||||
import { createObsidianVaultMarkdownDestination } from "../../../shared/obsidian/vault-write-destination.obsidian";
|
||||
import { createLocalIdSource } from "../application/local-id-source";
|
||||
import type { ChatPanelHandle, ChatPanelRuntimeSnapshot, ChatViewRuntimeOwner, CodexChatHost } from "./contracts";
|
||||
import { ChatPanelSession } from "./session";
|
||||
|
|
@ -46,7 +46,7 @@ export class CodexChatView extends ItemView {
|
|||
registerPointerDown: (handler) => {
|
||||
owner.registerDomEvent(this.containerEl.doc, "pointerdown", handler);
|
||||
},
|
||||
archiveDestination: () => createObsidianArchiveExportDestination(this.app.vault),
|
||||
archiveDestination: () => createObsidianVaultMarkdownDestination(this.app.vault),
|
||||
requestWorkspaceLayoutSave: () => {
|
||||
void this.app.workspace.requestSaveLayout();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@ import { Notice } from "obsidian";
|
|||
|
||||
import type { ObservedPaginatedResult } from "../../app-server/query/observed-result";
|
||||
import { observedInitialError, observedInitialLoading } from "../../app-server/query/observed-result";
|
||||
import type { ArchiveExportSettings } from "../../domain/threads/archive-markdown";
|
||||
import type { Thread } from "../../domain/threads/model";
|
||||
import type { ThreadRenameLifecycleEvent } from "../../domain/threads/rename-lifecycle";
|
||||
import { DeferredTask } from "../../shared/runtime/deferred-task";
|
||||
import { isStaleExecutionRuntimeError } from "../../shared/runtime/execution-runtime-lifetime";
|
||||
import { OwnerLifetime } from "../../shared/runtime/owner-lifetime";
|
||||
import type { ThreadCatalogEventSink, ThreadCatalogPaginatedActiveReader } from "../threads/catalog/thread-catalog";
|
||||
import type { ArchiveExportDestination } from "../threads/workflows/archive-export";
|
||||
import type { ArchiveExportDestination, ArchiveExportSettings } from "../threads/workflows/archive-export";
|
||||
import type { ThreadOperationsTransport, ThreadTitleTransport } from "../threads/workflows/ports";
|
||||
import type { ThreadNameMutationCoordinator } from "../threads/workflows/thread-name-mutation-coordinator";
|
||||
import { createThreadOperations, type ThreadOperations } from "../threads/workflows/thread-operations";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, ItemView, type WorkspaceLeaf } from "obsidian";
|
||||
|
||||
import { VIEW_TYPE_CODEX_THREADS } from "../../constants";
|
||||
import { createObsidianArchiveExportDestination } from "../threads/obsidian/archive-export-destination.obsidian";
|
||||
import { createObsidianVaultMarkdownDestination } from "../../shared/obsidian/vault-write-destination.obsidian";
|
||||
import { type ThreadsViewHost, ThreadsViewSession } from "./session";
|
||||
|
||||
export interface ThreadsRuntimeView {
|
||||
|
|
@ -38,7 +38,7 @@ export class CodexThreadsView extends ItemView {
|
|||
registerPointerDown: (handler) => {
|
||||
owner.registerDomEvent(this.containerEl.doc, "pointerdown", handler);
|
||||
},
|
||||
archiveDestination: () => createObsidianArchiveExportDestination(this.app.vault),
|
||||
archiveDestination: () => createObsidianVaultMarkdownDestination(this.app.vault),
|
||||
vaultConfigDir: () => this.app.vault.configDir,
|
||||
viewWindow: () => this.containerEl.doc.defaultView,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
import type { Vault } from "obsidian";
|
||||
import { createObsidianVaultMarkdownDestination } from "../../../shared/obsidian/vault-write-destination.obsidian";
|
||||
import type { ArchiveExportDestination } from "../workflows/archive-export";
|
||||
|
||||
export function createObsidianArchiveExportDestination(vault: Vault): ArchiveExportDestination {
|
||||
return createObsidianVaultMarkdownDestination(vault);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { type ArchiveExportSettings, type ArchiveThreadInput, archivedThreadMarkdown } from "../../../domain/threads/archive-markdown";
|
||||
import { type ArchiveMarkdownOptions, type ArchiveThreadInput, archivedThreadMarkdown } from "../../../domain/threads/archive-markdown";
|
||||
import { shortThreadId } from "../../../domain/threads/id";
|
||||
import { threadArchiveTitle } from "../../../domain/threads/title";
|
||||
import {
|
||||
|
|
@ -19,6 +19,11 @@ export interface ArchiveExportResult {
|
|||
path: string;
|
||||
}
|
||||
|
||||
export interface ArchiveExportSettings extends ArchiveMarkdownOptions {
|
||||
archiveExportFolderTemplate: string;
|
||||
archiveExportFilenameTemplate: string;
|
||||
}
|
||||
|
||||
export type ArchiveExportDestination = VaultMarkdownDestination;
|
||||
|
||||
interface TemplateContext {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import type { ArchiveExportSettings } from "../../../domain/threads/archive-markdown";
|
||||
import { normalizeExplicitThreadName, type Thread } from "../../../domain/threads/model";
|
||||
import { threadDisplayTitle } from "../../../domain/threads/title";
|
||||
import type { ThreadCatalogEventSink } from "../catalog/thread-catalog";
|
||||
import { type ArchiveExportDestination, exportArchivedThreadMarkdown } from "./archive-export";
|
||||
import { type ArchiveExportDestination, type ArchiveExportSettings, exportArchivedThreadMarkdown } from "./archive-export";
|
||||
import type { ThreadOperationsTransport } from "./ports";
|
||||
import type { ThreadNameMutationCoordinator } from "./thread-name-mutation-coordinator";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { type ArchiveExportSettings, archivedThreadMarkdown } from "../../../src/domain/threads/archive-markdown";
|
||||
import { type ArchiveMarkdownOptions, archivedThreadMarkdown } from "../../../src/domain/threads/archive-markdown";
|
||||
import type { Thread } from "../../../src/domain/threads/model";
|
||||
import type { ThreadTranscriptEntry } from "../../../src/domain/threads/transcript";
|
||||
|
||||
|
|
@ -300,13 +300,9 @@ describe("thread archive export", () => {
|
|||
function exportedMarkdown(
|
||||
source: Thread & { transcriptEntries: ThreadTranscriptEntry[] },
|
||||
now: Date,
|
||||
settings: Partial<ArchiveExportSettings> = {},
|
||||
settings: ArchiveMarkdownOptions = {},
|
||||
): string {
|
||||
return archivedThreadMarkdown(source, now, {
|
||||
archiveExportFolderTemplate: "Exports",
|
||||
archiveExportFilenameTemplate: "{{title}}",
|
||||
...settings,
|
||||
});
|
||||
return archivedThreadMarkdown(source, now, settings);
|
||||
}
|
||||
|
||||
function thread(
|
||||
|
|
|
|||
Loading…
Reference in a new issue