@lingxi-ai-cn/dsh-session-export 0.1.9-rc.1 → 0.1.11-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +7 -5
- package/README.zh.md +7 -5
- package/lib/index.js +14 -10
- package/lib/types/index.d.ts +4 -5
- package/package.json +14 -14
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/host/session-export/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 08694e65ca50f27bb950f153f4658f84d76ff013
|
|
6
|
+
README.zh.md: 3ed832c27850f6dd884a7c6a001f0c901233ba78
|
package/README.md
CHANGED
|
@@ -9,15 +9,17 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
Native Session archive writer and human-readable projection over the official [`@deepseek-ai/dsh-session-log-export`](../../session-query/session-log-export/README.md) producer. The `SessionLogExporter` service (`ctx.sessionLogExporter`) reuses that package's root preflight,
|
|
12
|
+
Native Session archive writer and human-readable projection over the official [`@deepseek-ai/dsh-session-log-export`](../../session-query/session-log-export/README.md) producer. The `SessionLogExporter` service (`ctx.sessionLogExporter`) reuses that package's root preflight, canonical logical-log ZIP stream, descendant ordering, attachment collection, compression, backpressure, and cancellation. `stream()` exposes the official archive stream to a native consumer; `writeToDirectory()` writes it into an existing absolute host directory and returns the exact final path. `writeMarkdownToDirectory()` separately reads validated logical events and publishes a summary-only Markdown projection.
|
|
13
|
+
|
|
14
|
+
## Native publication
|
|
13
15
|
|
|
14
16
|
The adapter adds only native publication: it creates an owner-only random sibling, forwards cancellation through the official producer and file writes, syncs and closes the complete file, then publishes it with an exclusive hard link. Existing exports are never overwritten: the first collision uses `-2`, followed by increasing suffixes. A failure before publication removes the partial sibling and leaves no final archive. The destination filesystem must support same-directory hard links.
|
|
15
17
|
|
|
16
18
|
Markdown export is intentionally a human-readable projection, not a replacement for the official raw archive. It includes the current surface of the root and optional descendants, bounded user/assistant text, tool names and bounded result summaries, and explicit sequence/time facts. Tool argument values are omitted and marked as omitted. Image attachments use `attachment:<id>` references and their bytes are never copied into the Markdown file. The same private sibling, cancellation, `0600` mode, collision suffix, and exclusive hard-link publication rules apply to `.md` output.
|
|
17
19
|
|
|
18
|
-
Expected preparation failures use `SessionLogExportError`: `services-unavailable`, `
|
|
20
|
+
Expected preparation failures use `SessionLogExportError`: `services-unavailable`, `session-not-found`, and `prepare-failed`. Destination and output failures use `destination-invalid` and `write-failed`. The operator-facing messages do not expose backend preparation errors; the original error remains attached as `cause` for host diagnostics. Signal cancellation preserves the signal's reason instead of becoming an export failure.
|
|
19
21
|
|
|
20
|
-
The archive is diagnostic material containing
|
|
22
|
+
The archive is diagnostic material containing validated Session events serialized as canonical JSONL. Provider credential stores and transient OAuth progress are outside Session persistence and are never included, but prompts and tool arguments already present in the durable log remain present; consumers must choose an operator-controlled destination and treat the result as sensitive.
|
|
21
23
|
|
|
22
24
|
## Table of Contents
|
|
23
25
|
|
|
@@ -42,8 +44,8 @@ None. Export does not assemble or send provider requests.
|
|
|
42
44
|
|
|
43
45
|
## Known Limitations and Deferred Work
|
|
44
46
|
|
|
45
|
-
-
|
|
46
|
-
- Markdown
|
|
47
|
+
- ZIP and Markdown export read logical events through read handles on JSONL and SQLite backends; the ZIP uses the current format's canonical filename. Physical compression and storage layout do not affect the exported log.
|
|
48
|
+
- Markdown attachment policy remains reference-only.
|
|
47
49
|
- A tree export is a sequence of per-Session durability barriers and reads, not one atomic snapshot across the whole lineage; a live descendant may append after its artifact was read.
|
|
48
50
|
- Native publication requires hard-link support in the selected directory. The service fails without publishing a partial final file when the filesystem rejects that operation.
|
|
49
51
|
|
package/README.zh.md
CHANGED
|
@@ -9,15 +9,17 @@ kind: "package-reference"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
基于官方 [`@deepseek-ai/dsh-session-log-export`](../../session-query/session-log-export/README.zh.md) 生产器的原生 Session 归档写入器与人类可读 projection。`SessionLogExporter` 服务(`ctx.sessionLogExporter
|
|
12
|
+
基于官方 [`@deepseek-ai/dsh-session-log-export`](../../session-query/session-log-export/README.zh.md) 生产器的原生 Session 归档写入器与人类可读 projection。`SessionLogExporter` 服务(`ctx.sessionLogExporter`)复用该包的根工件预检、规范逻辑日志 ZIP 流、后代顺序、附件收集、压缩、背压与取消。`stream()` 向原生消费方暴露官方归档流;`writeToDirectory()` 把它写入既有的绝对宿主目录,并返回精确的最终路径。`writeMarkdownToDirectory()` 则独立读取已验证的逻辑事件并发布仅供摘要阅读的 Markdown projection。
|
|
13
|
+
|
|
14
|
+
## 原生发布
|
|
13
15
|
|
|
14
16
|
该适配器只增加原生发布:先创建一个仅所有者可读写的随机同级文件,把取消转发到官方生产器和文件写入,随后同步并关闭完整文件,最后通过排他硬链接发布。既有导出永远不会被覆盖:第一次冲突使用 `-2`,随后递增后缀。发布前的失败会删除局部同级文件,不留下最终归档。目标文件系统必须支持同目录硬链接。
|
|
15
17
|
|
|
16
18
|
Markdown 导出明确是人类可读 projection,不替代官方原始归档。它包含根 Session 及可选后代的当前表层、有界的用户/助手文本、工具名称、有界结果摘要,以及明确的 seq/time 事实。工具参数值会被省略并明确标记。图片附件只使用 `attachment:<id>` 引用,其字节绝不复制到 Markdown 文件。同一私有同级临时文件、取消、`0600` 权限、冲突后缀和排他硬链接发布规则也适用于 `.md` 输出。
|
|
17
19
|
|
|
18
|
-
预期的准备失败使用 `SessionLogExportError`:`services-unavailable`、`
|
|
20
|
+
预期的准备失败使用 `SessionLogExportError`:`services-unavailable`、`session-not-found` 和 `prepare-failed`。目标与输出失败使用 `destination-invalid` 和 `write-failed`。面向操作者的消息不会泄露后端准备错误;原始错误保留为 `cause`,供宿主诊断。signal 取消会保留 signal 的 reason,而不会改写成导出失败。
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
该归档是将经过验证的 Session 事件序列化为规范 JSONL的诊断材料。提供方凭据存储和 transient OAuth 进度位于 Session 持久化之外,绝不会包含在内;但已经进入持久日志的 prompt 与工具参数仍会保留,因此 Consumer 必须选择由操作者控制的目标位置,并把结果视为敏感材料。
|
|
21
23
|
|
|
22
24
|
## 目录
|
|
23
25
|
|
|
@@ -45,8 +47,8 @@ Markdown 导出明确是人类可读 projection,不替代官方原始归档。
|
|
|
45
47
|
<a id="known-limitations-and-deferred-work"></a>
|
|
46
48
|
## 已知限制与暂缓事项
|
|
47
49
|
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
+
- ZIP 与 Markdown 导出均通过 JSONL 或 SQLite 后端的只读句柄读取逻辑事件;ZIP 使用当前格式的规范文件名。物理压缩方式与存储布局不影响导出的日志。
|
|
51
|
+
- Markdown 附件策略固定为仅引用。
|
|
50
52
|
- 树导出是一系列逐 Session 的持久性屏障与读取,并非覆盖整条血缘的一次原子快照;实时后代可能在自身工件被读取后继续追加。
|
|
51
53
|
- 原生发布要求所选目录支持硬链接。文件系统拒绝该操作时,服务会失败且不会发布局部最终文件。
|
|
52
54
|
|
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { link, open, rm, stat } from "node:fs/promises";
|
|
|
3
3
|
import { basename, extname, isAbsolute, join } from "node:path";
|
|
4
4
|
import { Service } from "@deepseek-ai/cordis";
|
|
5
5
|
import z from "@deepseek-ai/schemastery";
|
|
6
|
-
import { DEFAULT_SESSION_LOG_COMPRESSION_LEVEL, DEFAULT_SESSION_LOG_COMPRESSION_LEVEL as DEFAULT_SESSION_LOG_COMPRESSION_LEVEL$1, flushLiveSessionLog, flushLiveSessionLog as flushLiveSessionLog$1, sessionLogExportDeps, sessionLogExportDeps as sessionLogExportDeps$1, sessionLogZipEntries, sessionLogZipFilename, sessionLogZipFilename as sessionLogZipFilename$1, streamSessionLogZip, streamSessionLogZip as streamSessionLogZip$1 } from "@deepseek-ai/dsh-session-log-export";
|
|
6
|
+
import { DEFAULT_SESSION_LOG_COMPRESSION_LEVEL, DEFAULT_SESSION_LOG_COMPRESSION_LEVEL as DEFAULT_SESSION_LOG_COMPRESSION_LEVEL$1, flushLiveSessionLog, flushLiveSessionLog as flushLiveSessionLog$1, readSessionLogText, sessionLogExportDeps, sessionLogExportDeps as sessionLogExportDeps$1, sessionLogZipEntries, sessionLogZipFilename, sessionLogZipFilename as sessionLogZipFilename$1, streamSessionLogZip, streamSessionLogZip as streamSessionLogZip$1 } from "@deepseek-ai/dsh-session-log-export";
|
|
7
7
|
import { foldSurface } from "@deepseek-ai/dsh-session";
|
|
8
8
|
import { extractSessionEventText } from "@deepseek-ai/dsh-session-query";
|
|
9
9
|
//#region lib/types/markdown.js
|
|
@@ -93,12 +93,17 @@ async function loadMarkdownSource(deps, sessionId, signal) {
|
|
|
93
93
|
if (live !== void 0) await deps.sessions.flush(live);
|
|
94
94
|
}
|
|
95
95
|
signal.throwIfAborted();
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
96
|
+
const handle = await deps.sessionPersistence.open(sessionId, "read", { signal });
|
|
97
|
+
try {
|
|
98
|
+
const loaded = await handle.read(0, void 0, { signal });
|
|
99
|
+
signal.throwIfAborted();
|
|
100
|
+
return {
|
|
101
|
+
header: structuredClone(handle.header),
|
|
102
|
+
events: loaded.events.map((event) => structuredClone(event))
|
|
103
|
+
};
|
|
104
|
+
} finally {
|
|
105
|
+
await handle.close();
|
|
106
|
+
}
|
|
102
107
|
}
|
|
103
108
|
function appendSurface(lines, events) {
|
|
104
109
|
const bySeq = new Map(events.map((event) => [event.seq, event]));
|
|
@@ -229,7 +234,7 @@ var SessionLogExportError = class extends Error {
|
|
|
229
234
|
}
|
|
230
235
|
};
|
|
231
236
|
/**
|
|
232
|
-
* Flush and read the root
|
|
237
|
+
* Flush and read the root logical log before any ZIP byte is produced. Expected
|
|
233
238
|
* capability and persistence failures use {@link SessionLogExportError}; an
|
|
234
239
|
* aborted signal preserves its original reason.
|
|
235
240
|
* @param ctx - composed host context.
|
|
@@ -241,7 +246,6 @@ async function prepareSessionLogExport(ctx, sessionId, signal) {
|
|
|
241
246
|
signal.throwIfAborted();
|
|
242
247
|
const deps = sessionLogExportDeps$1(ctx);
|
|
243
248
|
if (deps.sessionQuery === void 0 || deps.sessionPersistence === void 0 || deps.attachments === void 0) throw new SessionLogExportError("services-unavailable", "session log export is unavailable: missing session-query, session-persistence, or attachments service");
|
|
244
|
-
if (!deps.sessionPersistence.supportsRawArtifacts) throw new SessionLogExportError("raw-artifacts-unsupported", "session log export is unavailable: the persistence backend does not expose per-session raw artifacts");
|
|
245
249
|
const ready = {
|
|
246
250
|
sessionQuery: deps.sessionQuery,
|
|
247
251
|
sessionPersistence: deps.sessionPersistence,
|
|
@@ -251,7 +255,7 @@ async function prepareSessionLogExport(ctx, sessionId, signal) {
|
|
|
251
255
|
let root;
|
|
252
256
|
try {
|
|
253
257
|
await flushLiveSessionLog$1(deps, sessionId, signal);
|
|
254
|
-
root = await deps.sessionPersistence
|
|
258
|
+
root = await readSessionLogText(deps.sessionPersistence, sessionId, signal);
|
|
255
259
|
signal.throwIfAborted();
|
|
256
260
|
} catch (error) {
|
|
257
261
|
signal.throwIfAborted();
|
package/lib/types/index.d.ts
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
import { Context, Service } from '@deepseek-ai/cordis';
|
|
8
8
|
import z from '@deepseek-ai/schemastery';
|
|
9
9
|
import type { SessionId } from '@deepseek-ai/dsh-session';
|
|
10
|
-
import type { SessionRawArtifact } from '@deepseek-ai/dsh-session-persistence';
|
|
11
10
|
import { type SessionLogCompressionLevel, type SessionLogExportReady } from '@deepseek-ai/dsh-session-log-export';
|
|
12
11
|
import type { SessionMarkdownExportRequest } from './markdown.ts';
|
|
13
12
|
export { DEFAULT_SESSION_LOG_COMPRESSION_LEVEL, flushLiveSessionLog, sessionLogExportDeps, sessionLogZipEntries, sessionLogZipFilename, streamSessionLogZip, } from '@deepseek-ai/dsh-session-log-export';
|
|
@@ -15,7 +14,7 @@ export type { SessionLogCompressionLevel, SessionLogExportDeps, SessionLogExport
|
|
|
15
14
|
export { renderSessionMarkdown, sessionMarkdownExportDeps, sessionMarkdownFilename, } from './markdown.ts';
|
|
16
15
|
export type { SessionMarkdownAttachmentPolicy, SessionMarkdownExportDeps, SessionMarkdownExportRequest, SessionMarkdownSessionStore, } from './markdown.ts';
|
|
17
16
|
/** Stable failure categories shared by the native writer and host transports. */
|
|
18
|
-
export type SessionLogExportErrorCode = 'services-unavailable' | '
|
|
17
|
+
export type SessionLogExportErrorCode = 'services-unavailable' | 'session-not-found' | 'prepare-failed' | 'destination-invalid' | 'write-failed';
|
|
19
18
|
/** Typed session-log export failure with a consumer-safe message. */
|
|
20
19
|
export declare class SessionLogExportError extends Error {
|
|
21
20
|
readonly code: SessionLogExportErrorCode;
|
|
@@ -30,8 +29,8 @@ export declare class SessionLogExportError extends Error {
|
|
|
30
29
|
export interface PreparedSessionLogExport {
|
|
31
30
|
/** Mounted services used while descendant and attachment entries stream. */
|
|
32
31
|
readonly ready: SessionLogExportReady;
|
|
33
|
-
/** Root
|
|
34
|
-
readonly root:
|
|
32
|
+
/** Root logical log already flushed and read for the first ZIP entry. */
|
|
33
|
+
readonly root: string;
|
|
35
34
|
}
|
|
36
35
|
/** One export request independent of its transport or destination. */
|
|
37
36
|
export interface SessionLogExportRequest {
|
|
@@ -70,7 +69,7 @@ declare module '@deepseek-ai/cordis' {
|
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
71
|
/**
|
|
73
|
-
* Flush and read the root
|
|
72
|
+
* Flush and read the root logical log before any ZIP byte is produced. Expected
|
|
74
73
|
* capability and persistence failures use {@link SessionLogExportError}; an
|
|
75
74
|
* aborted signal preserves its original reason.
|
|
76
75
|
* @param ctx - composed host context.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingxi-ai-cn/dsh-session-export",
|
|
3
3
|
"description": "Native atomic path writer over the official Session ZIP producer",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.11-rc.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"dependencies": {},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@deepseek-ai/cordis": "4.0.2",
|
|
36
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
37
|
-
"@deepseek-ai/dsh-invariants": "0.1.
|
|
38
|
-
"@deepseek-ai/dsh-session": "0.1.
|
|
39
|
-
"@deepseek-ai/dsh-session-log-export": "0.1.
|
|
40
|
-
"@deepseek-ai/dsh-session-persistence": "0.1.
|
|
41
|
-
"@deepseek-ai/dsh-session-query": "0.1.
|
|
36
|
+
"@deepseek-ai/dsh-attachment": "0.1.5-rc.2",
|
|
37
|
+
"@deepseek-ai/dsh-invariants": "0.1.5-rc.2",
|
|
38
|
+
"@deepseek-ai/dsh-session": "0.1.5-rc.2",
|
|
39
|
+
"@deepseek-ai/dsh-session-log-export": "0.1.5-rc.2",
|
|
40
|
+
"@deepseek-ai/dsh-session-persistence": "0.1.5-rc.2",
|
|
41
|
+
"@deepseek-ai/dsh-session-query": "0.1.5-rc.2",
|
|
42
42
|
"@deepseek-ai/schemastery": "3.18.2"
|
|
43
43
|
},
|
|
44
44
|
"peerDependenciesMeta": {
|
|
@@ -69,13 +69,13 @@
|
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@deepseek-ai/cordis": "4.0.2",
|
|
72
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
73
|
-
"@deepseek-ai/dsh-invariants": "0.1.
|
|
74
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
75
|
-
"@deepseek-ai/dsh-session": "0.1.
|
|
76
|
-
"@deepseek-ai/dsh-session-log-export": "0.1.
|
|
77
|
-
"@deepseek-ai/dsh-session-persistence": "0.1.
|
|
78
|
-
"@deepseek-ai/dsh-session-query": "0.1.
|
|
72
|
+
"@deepseek-ai/dsh-attachment": "0.1.5-rc.2",
|
|
73
|
+
"@deepseek-ai/dsh-invariants": "0.1.5-rc.2",
|
|
74
|
+
"@deepseek-ai/dsh-llm": "0.1.5-rc.2",
|
|
75
|
+
"@deepseek-ai/dsh-session": "0.1.5-rc.2",
|
|
76
|
+
"@deepseek-ai/dsh-session-log-export": "0.1.5-rc.2",
|
|
77
|
+
"@deepseek-ai/dsh-session-persistence": "0.1.5-rc.2",
|
|
78
|
+
"@deepseek-ai/dsh-session-query": "0.1.5-rc.2",
|
|
79
79
|
"@deepseek-ai/schemastery": "3.18.2",
|
|
80
80
|
"fflate": "^0.8.2"
|
|
81
81
|
}
|