@yefengr/pi-reach 0.0.6 → 0.0.7
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/files/content-type.d.ts +16 -0
- package/dist/files/content-type.js +98 -0
- package/dist/files/content-type.js.map +1 -0
- package/dist/files/image-structure.d.ts +21 -0
- package/dist/files/image-structure.js +269 -0
- package/dist/files/image-structure.js.map +1 -0
- package/dist/files/publications.d.ts +26 -0
- package/dist/files/publications.js +136 -0
- package/dist/files/publications.js.map +1 -0
- package/dist/files/publish-tool.d.ts +23 -0
- package/dist/files/publish-tool.js +70 -0
- package/dist/files/publish-tool.js.map +1 -0
- package/dist/files/reader.d.ts +66 -0
- package/dist/files/reader.js +416 -0
- package/dist/files/reader.js.map +1 -0
- package/dist/files/safe-open.d.ts +22 -0
- package/dist/files/safe-open.js +119 -0
- package/dist/files/safe-open.js.map +1 -0
- package/dist/index.js +12 -17
- package/dist/index.js.map +1 -1
- package/dist/runtime/file_binding.d.ts +25 -0
- package/dist/runtime/file_binding.js +49 -0
- package/dist/runtime/file_binding.js.map +1 -0
- package/dist/runtime/session_frame_router.d.ts +11 -0
- package/dist/runtime/session_frame_router.js +25 -0
- package/dist/runtime/session_frame_router.js.map +1 -0
- package/dist/timeline/runtime.d.ts +1 -1
- package/dist/timeline/runtime.js +26 -54
- package/dist/timeline/runtime.js.map +1 -1
- package/dist/timeline/system_event.d.ts +7 -0
- package/dist/timeline/system_event.js +58 -0
- package/dist/timeline/system_event.js.map +1 -0
- package/dist/timeline/tool_lifecycle.js +8 -2
- package/dist/timeline/tool_lifecycle.js.map +1 -1
- package/dist/timeline/v2_service.js +3 -0
- package/dist/timeline/v2_service.js.map +1 -1
- package/dist/vendor/protocol/session/files.d.ts +83 -0
- package/dist/vendor/protocol/session/files.js +162 -0
- package/dist/vendor/protocol/session/frames.d.ts +293 -18
- package/dist/vendor/protocol/session/frames.js +52 -2
- package/dist/vendor/protocol/session/index.d.ts +1 -0
- package/dist/vendor/protocol/session/index.js +1 -0
- package/dist/vendor/protocol/session/schema.d.ts +2 -2
- package/dist/vendor/protocol/session/schema.js +2 -0
- package/package.json +2 -2
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FileHandle } from "node:fs/promises";
|
|
2
|
+
import { type Dimensions } from "./image-structure.js";
|
|
3
|
+
type Preview = ({
|
|
4
|
+
kind: "image";
|
|
5
|
+
} & Dimensions) | {
|
|
6
|
+
kind: "text";
|
|
7
|
+
} | {
|
|
8
|
+
kind: "none";
|
|
9
|
+
};
|
|
10
|
+
type Inspection = {
|
|
11
|
+
mimeType: string;
|
|
12
|
+
preview: Preview;
|
|
13
|
+
};
|
|
14
|
+
/** 有界头识别不是完整解码认证;HTML/SVG 与所有文本都只能由消费端转义显示。 */
|
|
15
|
+
export declare function inspectFile(handle: FileHandle, byteLength: number, fileName: string): Promise<Inspection>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { extname } from "node:path";
|
|
2
|
+
import { FileAccessError } from "./safe-open.js";
|
|
3
|
+
import { ImageStructureReader, MAX_INSPECTION_READS, staticGif, staticPng, staticWebp } from "./image-structure.js";
|
|
4
|
+
const HEAD_MAX_BYTES = 256 * 1024;
|
|
5
|
+
const MAX_IMAGE_PIXELS = 20_000_000;
|
|
6
|
+
const NONE = { kind: "none" };
|
|
7
|
+
function image(mimeType, dimensions) {
|
|
8
|
+
if (!dimensions || dimensions.width <= 0 || dimensions.height <= 0 || dimensions.width * dimensions.height > MAX_IMAGE_PIXELS) {
|
|
9
|
+
return { mimeType, preview: NONE };
|
|
10
|
+
}
|
|
11
|
+
return { mimeType, preview: { kind: "image", ...dimensions } };
|
|
12
|
+
}
|
|
13
|
+
function jpegDimensions(head) {
|
|
14
|
+
let offset = 2;
|
|
15
|
+
while (offset < head.length) {
|
|
16
|
+
if (head[offset++] !== 0xff)
|
|
17
|
+
return undefined;
|
|
18
|
+
while (head[offset] === 0xff)
|
|
19
|
+
offset++;
|
|
20
|
+
if (offset >= head.length)
|
|
21
|
+
return undefined;
|
|
22
|
+
const marker = head[offset++];
|
|
23
|
+
if (marker === 0xd9 || marker === 0xda || marker === 0x00 || marker === 0xd8)
|
|
24
|
+
return undefined;
|
|
25
|
+
if (marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7))
|
|
26
|
+
continue;
|
|
27
|
+
if (offset + 2 > head.length)
|
|
28
|
+
return undefined;
|
|
29
|
+
const length = head.readUInt16BE(offset);
|
|
30
|
+
if (length < 2 || offset + length > head.length)
|
|
31
|
+
return undefined;
|
|
32
|
+
const sof = marker >= 0xc0 && marker <= 0xcf && ![0xc4, 0xc8, 0xcc].includes(marker);
|
|
33
|
+
if (sof) {
|
|
34
|
+
if (length < 8)
|
|
35
|
+
return undefined;
|
|
36
|
+
const components = head[offset + 7];
|
|
37
|
+
if (components < 1 || components > 4 || length !== 8 + 3 * components || ![8, 12, 16].includes(head[offset + 2]))
|
|
38
|
+
return undefined;
|
|
39
|
+
return { width: head.readUInt16BE(offset + 5), height: head.readUInt16BE(offset + 3) };
|
|
40
|
+
}
|
|
41
|
+
offset += length;
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
function isText(head, truncated) {
|
|
46
|
+
for (const byte of head) {
|
|
47
|
+
if ((byte < 0x20 && ![9, 10, 13].includes(byte)) || byte === 0x7f)
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
// 仅因头预算截断时允许末尾码点未完整;完整文件仍须 fatal 验证尾部。
|
|
52
|
+
const text = new TextDecoder("utf-8", { fatal: true }).decode(head, { stream: truncated });
|
|
53
|
+
return !/[\u0080-\u009f]/u.test(text);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** 有界头识别不是完整解码认证;HTML/SVG 与所有文本都只能由消费端转义显示。 */
|
|
60
|
+
export async function inspectFile(handle, byteLength, fileName) {
|
|
61
|
+
if (!Number.isSafeInteger(byteLength) || byteLength < 0)
|
|
62
|
+
throw new FileAccessError("io_error");
|
|
63
|
+
const buffer = Buffer.alloc(Math.min(byteLength, HEAD_MAX_BYTES));
|
|
64
|
+
let offset = 0;
|
|
65
|
+
let reads = 0;
|
|
66
|
+
// 保留短 read 的续读语义;实读头字节受 buffer 限制,重试另受操作预算限制。
|
|
67
|
+
while (offset < buffer.length && reads < MAX_INSPECTION_READS) {
|
|
68
|
+
const requested = buffer.length - offset;
|
|
69
|
+
reads++;
|
|
70
|
+
const { bytesRead } = await handle.read(buffer, offset, requested, offset);
|
|
71
|
+
if (bytesRead === 0)
|
|
72
|
+
throw new FileAccessError("file_changed");
|
|
73
|
+
if (!Number.isInteger(bytesRead) || bytesRead < 0 || bytesRead > requested)
|
|
74
|
+
throw new FileAccessError("io_error");
|
|
75
|
+
offset += bytesRead;
|
|
76
|
+
}
|
|
77
|
+
const head = buffer.subarray(0, offset);
|
|
78
|
+
const completeHead = offset === buffer.length;
|
|
79
|
+
const reader = new ImageStructureReader(handle, head, byteLength, reads);
|
|
80
|
+
if (head.length >= 8 && head.toString("hex", 0, 8) === "89504e470d0a1a0a")
|
|
81
|
+
return image("image/png", completeHead ? await staticPng(reader) : undefined);
|
|
82
|
+
if (head.length >= 3 && head[0] === 0xff && head[1] === 0xd8 && head[2] === 0xff)
|
|
83
|
+
return image("image/jpeg", completeHead ? jpegDimensions(head) : undefined);
|
|
84
|
+
if (head.length >= 6 && ["GIF87a", "GIF89a"].includes(head.toString("latin1", 0, 6)))
|
|
85
|
+
return image("image/gif", completeHead ? staticGif(head, byteLength) : undefined);
|
|
86
|
+
if (head.length >= 12 && head.toString("latin1", 0, 4) === "RIFF" && head.toString("latin1", 8, 12) === "WEBP") {
|
|
87
|
+
return image("image/webp", completeHead ? await staticWebp(reader) : undefined);
|
|
88
|
+
}
|
|
89
|
+
if (head.length >= 5 && head.toString("latin1", 0, 5) === "%PDF-")
|
|
90
|
+
return { mimeType: "application/pdf", preview: NONE };
|
|
91
|
+
if (head.length >= 4 && ["504b0304", "504b0506", "504b0708"].includes(head.toString("hex", 0, 4)))
|
|
92
|
+
return { mimeType: "application/zip", preview: NONE };
|
|
93
|
+
if (!completeHead || !isText(head, byteLength > head.length))
|
|
94
|
+
return { mimeType: "application/octet-stream", preview: NONE };
|
|
95
|
+
const markdown = [".md", ".markdown"].includes(extname(fileName).toLowerCase());
|
|
96
|
+
return { mimeType: markdown ? "text/markdown" : "text/plain", preview: { kind: "text" } };
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=content-type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-type.js","sourceRoot":"","sources":["../../src/files/content-type.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FileHandle } from "node:fs/promises";
|
|
2
|
+
export type Dimensions = {
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const MAX_INSPECTION_READS = 4096;
|
|
7
|
+
/** 只读取结构元数据;压缩数据按长度跳过,不认证像素内容或 CRC。 */
|
|
8
|
+
export declare class ImageStructureReader {
|
|
9
|
+
private readonly handle;
|
|
10
|
+
readonly head: Buffer;
|
|
11
|
+
readonly byteLength: number;
|
|
12
|
+
private reads;
|
|
13
|
+
private steps;
|
|
14
|
+
private metadataBytes;
|
|
15
|
+
constructor(handle: FileHandle, head: Buffer, byteLength: number, reads: number);
|
|
16
|
+
step(): boolean;
|
|
17
|
+
get(position: number, length: number): Promise<Buffer | undefined>;
|
|
18
|
+
}
|
|
19
|
+
export declare function staticPng(reader: ImageStructureReader): Promise<Dimensions | undefined>;
|
|
20
|
+
export declare function staticWebp(reader: ImageStructureReader): Promise<Dimensions | undefined>;
|
|
21
|
+
export declare function staticGif(head: Buffer, byteLength: number): Dimensions | undefined;
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { FileAccessError } from "./safe-open.js";
|
|
2
|
+
export const MAX_INSPECTION_READS = 4096;
|
|
3
|
+
const MAX_STRUCTURE_STEPS = 4096;
|
|
4
|
+
const MAX_METADATA_BYTES = 64 * 1024;
|
|
5
|
+
const PNG_ANCILLARY = new Set(["cHRM", "gAMA", "iCCP", "sBIT", "sRGB", "bKGD", "hIST", "tRNS", "pHYs", "sPLT", "tIME", "iTXt", "tEXt", "zTXt", "eXIf", "cICP", "mDCV", "cLLI"]);
|
|
6
|
+
/** 只读取结构元数据;压缩数据按长度跳过,不认证像素内容或 CRC。 */
|
|
7
|
+
export class ImageStructureReader {
|
|
8
|
+
handle;
|
|
9
|
+
head;
|
|
10
|
+
byteLength;
|
|
11
|
+
reads;
|
|
12
|
+
steps = 0;
|
|
13
|
+
metadataBytes = 0;
|
|
14
|
+
constructor(handle, head, byteLength, reads) {
|
|
15
|
+
this.handle = handle;
|
|
16
|
+
this.head = head;
|
|
17
|
+
this.byteLength = byteLength;
|
|
18
|
+
this.reads = reads;
|
|
19
|
+
}
|
|
20
|
+
step() { return ++this.steps <= MAX_STRUCTURE_STEPS; }
|
|
21
|
+
async get(position, length) {
|
|
22
|
+
if (!Number.isSafeInteger(position) || position < 0 || length < 0 || position + length > this.byteLength)
|
|
23
|
+
return undefined;
|
|
24
|
+
if (position + length <= this.head.length)
|
|
25
|
+
return this.head.subarray(position, position + length);
|
|
26
|
+
const buffer = Buffer.alloc(length);
|
|
27
|
+
let offset = Math.max(0, Math.min(length, this.head.length - position));
|
|
28
|
+
if (offset)
|
|
29
|
+
this.head.copy(buffer, 0, position, position + offset);
|
|
30
|
+
while (offset < length) {
|
|
31
|
+
const requested = length - offset;
|
|
32
|
+
// 按请求字节计费,短 read 也不能反复请求而突破 metadata I/O 预算。
|
|
33
|
+
if (this.reads >= MAX_INSPECTION_READS || this.metadataBytes + requested > MAX_METADATA_BYTES)
|
|
34
|
+
return undefined;
|
|
35
|
+
this.reads++;
|
|
36
|
+
this.metadataBytes += requested;
|
|
37
|
+
const { bytesRead } = await this.handle.read(buffer, offset, requested, position + offset);
|
|
38
|
+
if (bytesRead === 0)
|
|
39
|
+
throw new FileAccessError("file_changed");
|
|
40
|
+
if (!Number.isInteger(bytesRead) || bytesRead < 0 || bytesRead > requested)
|
|
41
|
+
throw new FileAccessError("io_error");
|
|
42
|
+
offset += bytesRead;
|
|
43
|
+
}
|
|
44
|
+
return buffer;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function pngHeader(head) {
|
|
48
|
+
if (head.length < 33 || head.readUInt32BE(8) !== 13 || head.toString("latin1", 12, 16) !== "IHDR")
|
|
49
|
+
return undefined;
|
|
50
|
+
const depths = { 0: [1, 2, 4, 8, 16], 2: [8, 16], 3: [1, 2, 4, 8], 4: [8, 16], 6: [8, 16] };
|
|
51
|
+
if (!depths[head[25]]?.includes(head[24]) || head[26] !== 0 || head[27] !== 0 || head[28] > 1)
|
|
52
|
+
return undefined;
|
|
53
|
+
const width = head.readUInt32BE(16);
|
|
54
|
+
const height = head.readUInt32BE(20);
|
|
55
|
+
if (width === 0 || height === 0 || width > 0x7fffffff || height > 0x7fffffff)
|
|
56
|
+
return undefined;
|
|
57
|
+
return { width, height };
|
|
58
|
+
}
|
|
59
|
+
export async function staticPng(reader) {
|
|
60
|
+
const dimensions = pngHeader(reader.head);
|
|
61
|
+
if (!dimensions)
|
|
62
|
+
return undefined;
|
|
63
|
+
let position = 33;
|
|
64
|
+
let dataSeen = false;
|
|
65
|
+
let dataStarted = false;
|
|
66
|
+
let dataEnded = false;
|
|
67
|
+
let paletteSeen = false;
|
|
68
|
+
while (position < reader.byteLength && reader.step()) {
|
|
69
|
+
const header = await reader.get(position, 8);
|
|
70
|
+
if (!header)
|
|
71
|
+
return undefined;
|
|
72
|
+
const length = header.readUInt32BE(0);
|
|
73
|
+
const type = header.toString("latin1", 4, 8);
|
|
74
|
+
const end = position + 12 + length;
|
|
75
|
+
if (length > 0x7fffffff || end > reader.byteLength)
|
|
76
|
+
return undefined;
|
|
77
|
+
// 动画声明在任何位置都不能放行;IEND 后也不得保留浏览器可解释的尾部。
|
|
78
|
+
if (["acTL", "fcTL", "fdAT"].includes(type))
|
|
79
|
+
return undefined;
|
|
80
|
+
if (type === "IEND") {
|
|
81
|
+
if (length !== 0 || !dataSeen || end !== reader.byteLength)
|
|
82
|
+
return undefined;
|
|
83
|
+
return await reader.get(position + 8, 4) ? dimensions : undefined;
|
|
84
|
+
}
|
|
85
|
+
if (type === "IDAT") {
|
|
86
|
+
if (dataEnded || (reader.head[25] === 3 && !paletteSeen))
|
|
87
|
+
return undefined;
|
|
88
|
+
dataStarted = true;
|
|
89
|
+
if (length > 0)
|
|
90
|
+
dataSeen = true;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
if (dataStarted)
|
|
94
|
+
dataEnded = true;
|
|
95
|
+
if (type === "PLTE") {
|
|
96
|
+
if (paletteSeen || dataStarted || !length || length > 768 || length % 3 || [0, 4].includes(reader.head[25]))
|
|
97
|
+
return undefined;
|
|
98
|
+
paletteSeen = true;
|
|
99
|
+
}
|
|
100
|
+
else if (!PNG_ANCILLARY.has(type))
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
// 中间 payload/checksum 按长度跳过,最终 IEND checksum 稀疏读确认 EOF。
|
|
104
|
+
position = end;
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
function webpPayload(type, data) {
|
|
109
|
+
if (type === "VP8 ") {
|
|
110
|
+
if (data.length < 10 || data[0] & 1 || data.toString("hex", 3, 6) !== "9d012a")
|
|
111
|
+
return undefined;
|
|
112
|
+
return { width: data.readUInt16LE(6) & 0x3fff, height: data.readUInt16LE(8) & 0x3fff };
|
|
113
|
+
}
|
|
114
|
+
if (data.length < 5 || data[0] !== 0x2f)
|
|
115
|
+
return undefined;
|
|
116
|
+
const bits = data.readUInt32LE(1);
|
|
117
|
+
if (bits >>> 29 !== 0)
|
|
118
|
+
return undefined;
|
|
119
|
+
return { width: (bits & 0x3fff) + 1, height: ((bits >>> 14) & 0x3fff) + 1 };
|
|
120
|
+
}
|
|
121
|
+
export async function staticWebp(reader) {
|
|
122
|
+
if (reader.head.readUInt32LE(4) + 8 !== reader.byteLength)
|
|
123
|
+
return undefined;
|
|
124
|
+
let position = 12;
|
|
125
|
+
let canvas;
|
|
126
|
+
let dimensions;
|
|
127
|
+
let flags = 0;
|
|
128
|
+
let imageType;
|
|
129
|
+
const seen = new Set();
|
|
130
|
+
let losslessAlpha = false;
|
|
131
|
+
while (position < reader.byteLength && reader.step()) {
|
|
132
|
+
const header = await reader.get(position, 8);
|
|
133
|
+
if (!header)
|
|
134
|
+
return undefined;
|
|
135
|
+
const type = header.toString("latin1", 0, 4);
|
|
136
|
+
const length = header.readUInt32LE(4);
|
|
137
|
+
const start = position + 8;
|
|
138
|
+
const end = start + length + (length & 1);
|
|
139
|
+
if (end > reader.byteLength || seen.has(type) || type === "ANIM" || type === "ANMF")
|
|
140
|
+
return undefined;
|
|
141
|
+
seen.add(type);
|
|
142
|
+
if (type === "VP8X") {
|
|
143
|
+
const data = length === 10 && position === 12 ? await reader.get(start, 10) : undefined;
|
|
144
|
+
if (!data || data[0] & 0xc3 || data[1] || data[2] || data[3])
|
|
145
|
+
return undefined;
|
|
146
|
+
flags = data[0];
|
|
147
|
+
canvas = { width: data.readUIntLE(4, 3) + 1, height: data.readUIntLE(7, 3) + 1 };
|
|
148
|
+
}
|
|
149
|
+
else if (type === "VP8 " || type === "VP8L") {
|
|
150
|
+
if (dimensions || (seen.has("ALPH") && type !== "VP8 "))
|
|
151
|
+
return undefined;
|
|
152
|
+
const required = type === "VP8 " ? 10 : 5;
|
|
153
|
+
const data = length >= required ? await reader.get(start, required) : undefined;
|
|
154
|
+
if (!data)
|
|
155
|
+
return undefined;
|
|
156
|
+
dimensions = webpPayload(type, data);
|
|
157
|
+
if (!dimensions || !dimensions.width || !dimensions.height)
|
|
158
|
+
return undefined;
|
|
159
|
+
imageType = type;
|
|
160
|
+
losslessAlpha = type === "VP8L" && !!(data[4] & 0x10);
|
|
161
|
+
if (canvas && (canvas.width !== dimensions.width || canvas.height !== dimensions.height))
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
else if (type === "ICCP" || type === "ALPH" || type === "EXIF" || type === "XMP ") {
|
|
165
|
+
if (!canvas || !length)
|
|
166
|
+
return undefined;
|
|
167
|
+
if ((type === "ICCP" || type === "ALPH") && dimensions)
|
|
168
|
+
return undefined;
|
|
169
|
+
if ((type === "EXIF" || type === "XMP ") && !dimensions)
|
|
170
|
+
return undefined;
|
|
171
|
+
if (type === "ALPH") {
|
|
172
|
+
const data = await reader.get(start, 1);
|
|
173
|
+
if (!data || data[0] & 0xc0 || (data[0] & 3) > 1 || ((data[0] >> 4) & 3) > 1)
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else
|
|
178
|
+
return undefined;
|
|
179
|
+
if (length & 1) {
|
|
180
|
+
const padding = await reader.get(end - 1, 1);
|
|
181
|
+
if (!padding || padding[0] !== 0)
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
position = end;
|
|
185
|
+
}
|
|
186
|
+
if (position !== reader.byteLength || !dimensions)
|
|
187
|
+
return undefined;
|
|
188
|
+
if (canvas && (Boolean(flags & 0x20) !== seen.has("ICCP") || Boolean(flags & 0x08) !== seen.has("EXIF")
|
|
189
|
+
|| Boolean(flags & 0x04) !== seen.has("XMP ") || Boolean(flags & 0x10) !== (seen.has("ALPH") || losslessAlpha)))
|
|
190
|
+
return undefined;
|
|
191
|
+
if (!canvas && (seen.size !== 1 || (imageType !== "VP8 " && imageType !== "VP8L")))
|
|
192
|
+
return undefined;
|
|
193
|
+
// 即使最后一个压缩 payload 没有 padding,也确认声明的文件末字节存在。
|
|
194
|
+
return await reader.get(reader.byteLength - 1, 1) ? dimensions : undefined;
|
|
195
|
+
}
|
|
196
|
+
export function staticGif(head, byteLength) {
|
|
197
|
+
// GIF 的压缩块不能稀疏跳过证明帧数;超过已有头预算时仅提供下载。
|
|
198
|
+
if (head.length !== byteLength || head.length < 13)
|
|
199
|
+
return undefined;
|
|
200
|
+
const dimensions = { width: head.readUInt16LE(6), height: head.readUInt16LE(8) };
|
|
201
|
+
if (!dimensions.width || !dimensions.height)
|
|
202
|
+
return undefined;
|
|
203
|
+
const globalTable = !!(head[10] & 0x80);
|
|
204
|
+
let position = 13 + (globalTable ? 3 * 2 ** ((head[10] & 7) + 1) : 0);
|
|
205
|
+
let steps = 0;
|
|
206
|
+
let frames = 0;
|
|
207
|
+
let controlPending = false;
|
|
208
|
+
const step = () => ++steps <= MAX_STRUCTURE_STEPS;
|
|
209
|
+
const subblocks = (requireData) => {
|
|
210
|
+
let dataSeen = false;
|
|
211
|
+
while (position < head.length && step()) {
|
|
212
|
+
const length = head[position++];
|
|
213
|
+
if (!length)
|
|
214
|
+
return !requireData || dataSeen;
|
|
215
|
+
dataSeen = true;
|
|
216
|
+
position += length;
|
|
217
|
+
if (position > head.length)
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
return false;
|
|
221
|
+
};
|
|
222
|
+
while (position < head.length && step()) {
|
|
223
|
+
const type = head[position++];
|
|
224
|
+
if (type === 0x3b)
|
|
225
|
+
return frames === 1 && !controlPending && position === head.length ? dimensions : undefined;
|
|
226
|
+
if (type === 0x21) {
|
|
227
|
+
const label = head[position++];
|
|
228
|
+
if (label === 0xf9) {
|
|
229
|
+
if (controlPending || position + 6 > head.length || head[position] !== 4 || head[position + 5] !== 0)
|
|
230
|
+
return undefined;
|
|
231
|
+
const packed = head[position + 1];
|
|
232
|
+
if (packed & 0xe0 || ((packed >> 2) & 7) > 3)
|
|
233
|
+
return undefined;
|
|
234
|
+
controlPending = true;
|
|
235
|
+
position += 6;
|
|
236
|
+
}
|
|
237
|
+
else if (label === 0xfe) {
|
|
238
|
+
if (!subblocks(false))
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
// Plain Text 可产生额外渲染;应用扩展语义未知,不能证明静态。
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (type !== 0x2c || ++frames !== 1 || position + 9 > head.length)
|
|
248
|
+
return undefined;
|
|
249
|
+
const left = head.readUInt16LE(position);
|
|
250
|
+
const top = head.readUInt16LE(position + 2);
|
|
251
|
+
const width = head.readUInt16LE(position + 4);
|
|
252
|
+
const height = head.readUInt16LE(position + 6);
|
|
253
|
+
const packed = head[position + 8];
|
|
254
|
+
if (!width || !height || left + width > dimensions.width || top + height > dimensions.height || packed & 0x18)
|
|
255
|
+
return undefined;
|
|
256
|
+
const localTable = !!(packed & 0x80);
|
|
257
|
+
if (!globalTable && !localTable)
|
|
258
|
+
return undefined;
|
|
259
|
+
position += 9 + (localTable ? 3 * 2 ** ((packed & 7) + 1) : 0);
|
|
260
|
+
if (position >= head.length || head[position] < 2 || head[position] > 8)
|
|
261
|
+
return undefined;
|
|
262
|
+
position++;
|
|
263
|
+
if (!subblocks(true))
|
|
264
|
+
return undefined;
|
|
265
|
+
controlPending = false;
|
|
266
|
+
}
|
|
267
|
+
return undefined;
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=image-structure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-structure.js","sourceRoot":"","sources":["../../src/files/image-structure.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type SessionManager } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type PublishedFileMetadata } from "../vendor/protocol/session/index.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
export declare const PUBLISHED_FILE_TOOL_NAME: "publish_file";
|
|
5
|
+
export type ConfirmedPublication = {
|
|
6
|
+
id: string;
|
|
7
|
+
sourcePath: string;
|
|
8
|
+
metadata: PublishedFileMetadata;
|
|
9
|
+
groupId?: string;
|
|
10
|
+
timestamp: number;
|
|
11
|
+
branchPosition: number;
|
|
12
|
+
};
|
|
13
|
+
/** 只存于原生 custom;不能把此 schema 当作 wire payload。 */
|
|
14
|
+
export declare const publicationDataSchema: z.ZodObject<{
|
|
15
|
+
file_name: z.ZodString;
|
|
16
|
+
mime_type: z.ZodString;
|
|
17
|
+
byte_length: z.ZodNumber;
|
|
18
|
+
tool_call_id: z.ZodString;
|
|
19
|
+
source_path: z.ZodString;
|
|
20
|
+
group_id: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strict>;
|
|
22
|
+
/**
|
|
23
|
+
* 原生成功 toolResult 是确认点,且 custom/result 两者均须已落盘。
|
|
24
|
+
* 失败 append 留下的内部孤立记录无资格;不尝试回滚 SDK 的 append-only 树。
|
|
25
|
+
*/
|
|
26
|
+
export declare function collectPublications(manager: SessionManager): Map<string, ConfirmedPublication>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, resolve } from "node:path";
|
|
3
|
+
import { isDeepStrictEqual } from "node:util";
|
|
4
|
+
import { parseSessionEntries } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { idSchema, PUBLISHED_FILE_TYPE, publishedFileMetadataSchema } from "../vendor/protocol/session/index.js";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
export const PUBLISHED_FILE_TOOL_NAME = "publish_file";
|
|
8
|
+
/** 只存于原生 custom;不能把此 schema 当作 wire payload。 */
|
|
9
|
+
export const publicationDataSchema = publishedFileMetadataSchema.extend({
|
|
10
|
+
source_path: z.string().min(1).refine((path) => !path.includes("\0") && isAbsolute(path) && resolve(path) === path),
|
|
11
|
+
group_id: idSchema.optional(),
|
|
12
|
+
}).strict();
|
|
13
|
+
const resultDetailsSchema = z.object({ publication_id: idSchema }).strict();
|
|
14
|
+
// 一个 manager 最多保留一个文件的解析结果;manager 回收时缓存随之回收。
|
|
15
|
+
const diskProofs = new WeakMap();
|
|
16
|
+
function sameFile(left, right) {
|
|
17
|
+
return left.dev === right.dev && left.ino === right.ino && left.size === right.size
|
|
18
|
+
&& left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs;
|
|
19
|
+
}
|
|
20
|
+
function diskEntries(manager) {
|
|
21
|
+
try {
|
|
22
|
+
const path = manager.getSessionFile();
|
|
23
|
+
if (!path)
|
|
24
|
+
return null;
|
|
25
|
+
const before = statSync(path, { bigint: true });
|
|
26
|
+
if (!before.isFile())
|
|
27
|
+
return null;
|
|
28
|
+
const cached = diskProofs.get(manager);
|
|
29
|
+
if (cached?.path === path && sameFile(cached.stat, before))
|
|
30
|
+
return cached.entries;
|
|
31
|
+
const entries = parseSessionEntries(readFileSync(path, "utf8"));
|
|
32
|
+
const after = statSync(path, { bigint: true });
|
|
33
|
+
if (!after.isFile() || !sameFile(before, after))
|
|
34
|
+
return null;
|
|
35
|
+
diskProofs.set(manager, { path, stat: after, entries });
|
|
36
|
+
return entries;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
diskProofs.delete(manager);
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function record(value) {
|
|
44
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
45
|
+
}
|
|
46
|
+
/** JSONL 不存 undefined 字段;比较完整原生记录而非只比较 publication_id。 */
|
|
47
|
+
function samePersistedEntry(current, persisted) {
|
|
48
|
+
return isDeepStrictEqual(JSON.parse(JSON.stringify(current)), persisted);
|
|
49
|
+
}
|
|
50
|
+
function addByCall(map, callId, value) {
|
|
51
|
+
if (typeof callId !== "string")
|
|
52
|
+
return;
|
|
53
|
+
const matches = map.get(callId) ?? [];
|
|
54
|
+
matches.push(value);
|
|
55
|
+
map.set(callId, matches);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 原生成功 toolResult 是确认点,且 custom/result 两者均须已落盘。
|
|
59
|
+
* 失败 append 留下的内部孤立记录无资格;不尝试回滚 SDK 的 append-only 树。
|
|
60
|
+
*/
|
|
61
|
+
export function collectPublications(manager) {
|
|
62
|
+
const confirmed = new Map();
|
|
63
|
+
try {
|
|
64
|
+
const persisted = diskEntries(manager);
|
|
65
|
+
if (!persisted)
|
|
66
|
+
return confirmed;
|
|
67
|
+
const headers = persisted.filter((entry) => record(entry) && entry.type === "session");
|
|
68
|
+
const header = manager.getHeader();
|
|
69
|
+
if (headers.length !== 1 || persisted[0] !== headers[0] || !header
|
|
70
|
+
|| header.id !== manager.getSessionId() || !samePersistedEntry(header, headers[0]))
|
|
71
|
+
return confirmed;
|
|
72
|
+
const diskById = new Map();
|
|
73
|
+
for (const entry of persisted) {
|
|
74
|
+
if (!record(entry) || !idSchema.safeParse(entry.id).success || diskById.has(entry.id))
|
|
75
|
+
return confirmed;
|
|
76
|
+
diskById.set(entry.id, entry);
|
|
77
|
+
}
|
|
78
|
+
const branch = manager.getBranch();
|
|
79
|
+
const customs = new Map();
|
|
80
|
+
const results = new Map();
|
|
81
|
+
const branchIds = new Set();
|
|
82
|
+
const persistedPrefixes = [];
|
|
83
|
+
let persistedPrefix = true;
|
|
84
|
+
for (let index = 0; index < branch.length; index++) {
|
|
85
|
+
const entry = branch[index];
|
|
86
|
+
if (branchIds.has(entry.id) || entry.parentId !== (index === 0 ? null : branch[index - 1].id))
|
|
87
|
+
return confirmed;
|
|
88
|
+
branchIds.add(entry.id);
|
|
89
|
+
const diskEntry = diskById.get(entry.id);
|
|
90
|
+
persistedPrefix = persistedPrefix && diskEntry?.type === entry.type
|
|
91
|
+
&& "parentId" in diskEntry && diskEntry.parentId === entry.parentId;
|
|
92
|
+
persistedPrefixes.push(persistedPrefix);
|
|
93
|
+
if (entry.type === "custom" && entry.customType === PUBLISHED_FILE_TYPE) {
|
|
94
|
+
addByCall(customs, record(entry.data) ? entry.data.tool_call_id : undefined, { entry, index });
|
|
95
|
+
}
|
|
96
|
+
else if (entry.type === "message" && entry.message.role === "toolResult" && entry.message.toolName === PUBLISHED_FILE_TOOL_NAME) {
|
|
97
|
+
addByCall(results, entry.message.toolCallId, { entry, index });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const candidates = [];
|
|
101
|
+
for (const [callId, matches] of customs) {
|
|
102
|
+
const tools = results.get(callId);
|
|
103
|
+
if (matches.length !== 1 || tools?.length !== 1)
|
|
104
|
+
continue;
|
|
105
|
+
const custom = matches[0];
|
|
106
|
+
const result = tools[0];
|
|
107
|
+
const data = publicationDataSchema.safeParse(custom.entry.data);
|
|
108
|
+
const message = result.entry.message;
|
|
109
|
+
if (!data.success || message.role !== "toolResult" || message.isError !== false
|
|
110
|
+
|| result.index <= custom.index || !persistedPrefixes[result.index])
|
|
111
|
+
continue;
|
|
112
|
+
const details = resultDetailsSchema.safeParse(message.details);
|
|
113
|
+
const timestamp = Date.parse(custom.entry.timestamp);
|
|
114
|
+
if (!details.success || details.data.publication_id !== custom.entry.id || !Number.isFinite(timestamp) || timestamp < 0)
|
|
115
|
+
continue;
|
|
116
|
+
if (!samePersistedEntry(custom.entry, diskById.get(custom.entry.id))
|
|
117
|
+
|| !samePersistedEntry(result.entry, diskById.get(result.entry.id)))
|
|
118
|
+
continue;
|
|
119
|
+
const { source_path, group_id, ...metadata } = data.data;
|
|
120
|
+
candidates.push({
|
|
121
|
+
id: custom.entry.id, sourcePath: source_path, metadata, timestamp,
|
|
122
|
+
...(group_id === undefined ? {} : { groupId: group_id }),
|
|
123
|
+
branchPosition: result.index + 0.5,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
candidates.sort((left, right) => left.branchPosition - right.branchPosition);
|
|
127
|
+
for (const candidate of candidates)
|
|
128
|
+
confirmed.set(candidate.id, candidate);
|
|
129
|
+
return confirmed;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// 不可信或无法读取的原生记录只能拒绝资格,不能降级为内存证明。
|
|
133
|
+
return new Map();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=publications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publications.js","sourceRoot":"","sources":["../../src/files/publications.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SessionManager, ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
declare const parameters: Type.TObject<{
|
|
4
|
+
path: Type.TString;
|
|
5
|
+
}>;
|
|
6
|
+
export type PublishFileToolOptions = {
|
|
7
|
+
getManager: () => SessionManager | null;
|
|
8
|
+
isCurrent: () => boolean;
|
|
9
|
+
getGeneration: () => number;
|
|
10
|
+
getGroupId: () => string | null;
|
|
11
|
+
/** 仅在共享资源账目中完成 inspection 并关闭句柄后 resolve。 */
|
|
12
|
+
inspect: (absolutePath: string) => Promise<{
|
|
13
|
+
sourcePath: string;
|
|
14
|
+
fileName: string;
|
|
15
|
+
mimeType: string;
|
|
16
|
+
byteLength: number;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
export type PublishFileToolDetails = {
|
|
20
|
+
publication_id: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function createPublishFileTool(options: PublishFileToolOptions): ToolDefinition<typeof parameters, PublishFileToolDetails>;
|
|
23
|
+
export {};
|