get-pfm 0.1.0

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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -0
  3. package/dist/cjs/__tests__/index.test.cjs +292 -0
  4. package/dist/cjs/__tests__/index.test.cjs.map +1 -0
  5. package/dist/cjs/__tests__/index.test.d.cts +4 -0
  6. package/dist/cjs/checksum.cjs +132 -0
  7. package/dist/cjs/checksum.cjs.map +1 -0
  8. package/dist/cjs/checksum.d.cts +35 -0
  9. package/dist/cjs/convert.cjs +120 -0
  10. package/dist/cjs/convert.cjs.map +1 -0
  11. package/dist/cjs/convert.d.cts +31 -0
  12. package/dist/cjs/index.cjs +45 -0
  13. package/dist/cjs/index.cjs.map +1 -0
  14. package/dist/cjs/index.d.cts +26 -0
  15. package/dist/cjs/parser.cjs +195 -0
  16. package/dist/cjs/parser.cjs.map +1 -0
  17. package/dist/cjs/parser.d.cts +55 -0
  18. package/dist/cjs/serialize.cjs +146 -0
  19. package/dist/cjs/serialize.cjs.map +1 -0
  20. package/dist/cjs/serialize.d.cts +33 -0
  21. package/dist/cjs/types.cjs +29 -0
  22. package/dist/cjs/types.cjs.map +1 -0
  23. package/dist/cjs/types.d.cts +55 -0
  24. package/dist/esm/__tests__/conformance.test.d.ts +9 -0
  25. package/dist/esm/__tests__/conformance.test.d.ts.map +1 -0
  26. package/dist/esm/__tests__/conformance.test.js +170 -0
  27. package/dist/esm/__tests__/conformance.test.js.map +1 -0
  28. package/dist/esm/__tests__/index.test.d.ts +5 -0
  29. package/dist/esm/__tests__/index.test.d.ts.map +1 -0
  30. package/dist/esm/__tests__/index.test.js +287 -0
  31. package/dist/esm/__tests__/index.test.js.map +1 -0
  32. package/dist/esm/checksum.d.ts +36 -0
  33. package/dist/esm/checksum.d.ts.map +1 -0
  34. package/dist/esm/checksum.js +95 -0
  35. package/dist/esm/checksum.js.map +1 -0
  36. package/dist/esm/convert.d.ts +32 -0
  37. package/dist/esm/convert.d.ts.map +1 -0
  38. package/dist/esm/convert.js +115 -0
  39. package/dist/esm/convert.js.map +1 -0
  40. package/dist/esm/index.d.ts +27 -0
  41. package/dist/esm/index.d.ts.map +1 -0
  42. package/dist/esm/index.js +30 -0
  43. package/dist/esm/index.js.map +1 -0
  44. package/dist/esm/parser.d.ts +56 -0
  45. package/dist/esm/parser.d.ts.map +1 -0
  46. package/dist/esm/parser.js +189 -0
  47. package/dist/esm/parser.js.map +1 -0
  48. package/dist/esm/serialize.d.ts +34 -0
  49. package/dist/esm/serialize.d.ts.map +1 -0
  50. package/dist/esm/serialize.js +143 -0
  51. package/dist/esm/serialize.js.map +1 -0
  52. package/dist/esm/types.d.ts +56 -0
  53. package/dist/esm/types.d.ts.map +1 -0
  54. package/dist/esm/types.js +26 -0
  55. package/dist/esm/types.js.map +1 -0
  56. package/package.json +55 -0
@@ -0,0 +1,33 @@
1
+ /**
2
+ * PFM Serializer — Write PFM documents back to text.
3
+ *
4
+ * Mirrors the Python PFMWriter logic:
5
+ * - Magic line with format version
6
+ * - Meta section with key: value pairs
7
+ * - Index section with byte offsets
8
+ * - Content sections with escape of #@ and #! prefixes
9
+ * - EOF marker
10
+ */
11
+ import type { PFMDocument } from './types.js';
12
+ /**
13
+ * Serialize a PFMDocument to .pfm text format.
14
+ *
15
+ * Computes checksum and byte-offset index automatically.
16
+ *
17
+ * @param doc - The document to serialize.
18
+ * @returns The complete .pfm file content as a string.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { serialize } from 'pfm';
23
+ *
24
+ * const text = await serialize({
25
+ * formatVersion: '1.0',
26
+ * isStream: false,
27
+ * meta: { id: 'abc', agent: 'my-agent', model: 'gpt-4' },
28
+ * sections: [{ name: 'content', content: 'Hello, world!' }],
29
+ * });
30
+ * fs.writeFileSync('output.pfm', text);
31
+ * ```
32
+ */
33
+ export declare function serialize(doc: PFMDocument): Promise<string>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * PFM Types — TypeScript definitions for the PFM file format.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SECTION_TYPES = exports.META_FIELDS = void 0;
7
+ /** Known standard metadata field descriptions. */
8
+ exports.META_FIELDS = {
9
+ id: 'Unique document identifier (UUID v4)',
10
+ agent: 'Name/identifier of the generating agent',
11
+ model: 'Model ID used for generation',
12
+ created: 'ISO-8601 creation timestamp',
13
+ checksum: 'SHA-256 hash of all content sections',
14
+ parent: 'ID of parent .pfm document (for chains)',
15
+ tags: 'Comma-separated tags',
16
+ version: 'Document version (user-defined)',
17
+ };
18
+ /** Known standard section type descriptions. */
19
+ exports.SECTION_TYPES = {
20
+ content: 'Primary output content from the agent',
21
+ chain: 'Prompt chain / conversation that produced this output',
22
+ tools: 'Tool calls made during generation',
23
+ artifacts: 'Generated code, files, or structured data',
24
+ reasoning: 'Agent reasoning / chain-of-thought',
25
+ context: 'Context window snapshot at generation time',
26
+ errors: 'Errors encountered during generation',
27
+ metrics: 'Performance metrics (tokens, latency, cost)',
28
+ };
29
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAsDH,kDAAkD;AACrC,QAAA,WAAW,GAA2B;IACjD,EAAE,EAAE,sCAAsC;IAC1C,KAAK,EAAE,yCAAyC;IAChD,KAAK,EAAE,8BAA8B;IACrC,OAAO,EAAE,6BAA6B;IACtC,QAAQ,EAAE,sCAAsC;IAChD,MAAM,EAAE,yCAAyC;IACjD,IAAI,EAAE,sBAAsB;IAC5B,OAAO,EAAE,iCAAiC;CAC3C,CAAC;AAEF,gDAAgD;AACnC,QAAA,aAAa,GAA2B;IACnD,OAAO,EAAE,uCAAuC;IAChD,KAAK,EAAE,uDAAuD;IAC9D,KAAK,EAAE,mCAAmC;IAC1C,SAAS,EAAE,2CAA2C;IACtD,SAAS,EAAE,oCAAoC;IAC/C,OAAO,EAAE,4CAA4C;IACrD,MAAM,EAAE,sCAAsC;IAC9C,OAAO,EAAE,6CAA6C;CACvD,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * PFM Types — TypeScript definitions for the PFM file format.
3
+ */
4
+ /** A single section in a PFM document. */
5
+ export interface PFMSection {
6
+ /** Section name (e.g. "content", "chain", "tools"). */
7
+ name: string;
8
+ /** Section content (unescaped). */
9
+ content: string;
10
+ }
11
+ /** Parsed metadata from a PFM document. */
12
+ export interface PFMMeta {
13
+ /** Unique document identifier (UUID v4). */
14
+ id?: string;
15
+ /** Name/identifier of the generating agent. */
16
+ agent?: string;
17
+ /** Model ID used for generation. */
18
+ model?: string;
19
+ /** ISO-8601 creation timestamp. */
20
+ created?: string;
21
+ /** SHA-256 hash of all content sections. */
22
+ checksum?: string;
23
+ /** ID of parent .pfm document (for chains). */
24
+ parent?: string;
25
+ /** Comma-separated tags. */
26
+ tags?: string;
27
+ /** Document version (user-defined). */
28
+ version?: string;
29
+ /** Any additional custom metadata fields. */
30
+ [key: string]: string | undefined;
31
+ }
32
+ /** A fully parsed PFM document. */
33
+ export interface PFMDocument {
34
+ /** Format version (e.g. "1.0"). */
35
+ formatVersion: string;
36
+ /** Whether this is a streaming-mode document. */
37
+ isStream: boolean;
38
+ /** Document metadata. */
39
+ meta: PFMMeta;
40
+ /** Content sections (in order). */
41
+ sections: PFMSection[];
42
+ }
43
+ /** Result of checksum validation. */
44
+ export interface ChecksumResult {
45
+ /** Whether the checksum is valid. */
46
+ valid: boolean;
47
+ /** Expected checksum from metadata (empty string if missing). */
48
+ expected: string;
49
+ /** Computed checksum from section contents. */
50
+ computed: string;
51
+ }
52
+ /** Known standard metadata field descriptions. */
53
+ export declare const META_FIELDS: Record<string, string>;
54
+ /** Known standard section type descriptions. */
55
+ export declare const SECTION_TYPES: Record<string, string>;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * PFM Cross-Implementation Conformance Tests
3
+ *
4
+ * Loads shared test vectors from tests/conformance/vectors.json
5
+ * and runs them against the JS parser/serializer.
6
+ * Both Python and JS implementations MUST pass all of these.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=conformance.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/conformance.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * PFM Cross-Implementation Conformance Tests
3
+ *
4
+ * Loads shared test vectors from tests/conformance/vectors.json
5
+ * and runs them against the JS parser/serializer.
6
+ * Both Python and JS implementations MUST pass all of these.
7
+ */
8
+ import { describe, it } from 'node:test';
9
+ import assert from 'node:assert/strict';
10
+ import { readFileSync } from 'node:fs';
11
+ import { resolve, dirname } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { parse, serialize, computeChecksum } from '../index.js';
14
+ const __dirname = dirname(fileURLToPath(import.meta.url));
15
+ // Find vectors.json by walking up to the pfm-js dir, then up to repo root
16
+ // Works from both src/__tests__/ (2 up) and dist/esm/__tests__/ (3 up)
17
+ function findVectors() {
18
+ for (let levels = 2; levels <= 4; levels++) {
19
+ const candidate = resolve(__dirname, ...Array(levels).fill('..'), 'tests', 'conformance', 'vectors.json');
20
+ try {
21
+ readFileSync(candidate);
22
+ return candidate;
23
+ }
24
+ catch { /* next */ }
25
+ }
26
+ throw new Error('vectors.json not found');
27
+ }
28
+ const VECTORS_PATH = findVectors();
29
+ const vectors = JSON.parse(readFileSync(VECTORS_PATH, 'utf-8'));
30
+ // ================================================================
31
+ // Escape Round-Trip Tests
32
+ // ================================================================
33
+ describe('conformance: escape round-trip', () => {
34
+ for (const c of vectors.escape_roundtrip.cases) {
35
+ it(`[${c.desc}] serialize -> parse preserves content`, async () => {
36
+ // Create a doc with this content, serialize, parse back
37
+ const doc = {
38
+ formatVersion: '1.0',
39
+ isStream: false,
40
+ meta: { agent: 'conformance-test' },
41
+ sections: [{ name: 'content', content: c.input }],
42
+ };
43
+ const text = await serialize(doc);
44
+ const restored = parse(text);
45
+ assert.equal(restored.sections[0].content, c.input, `Round-trip failed for ${JSON.stringify(c.input)}`);
46
+ });
47
+ }
48
+ it('multi-roundtrip stability (10x escape/unescape)', async () => {
49
+ const dangerous = ['#@section', '#!PFM/1.0', '#!END', '\\#@marker', '\\\\#@deep'];
50
+ for (const original of dangerous) {
51
+ // Escape 10 times by nesting in serialize/parse
52
+ let content = original;
53
+ for (let i = 0; i < 10; i++) {
54
+ const doc = {
55
+ formatVersion: '1.0',
56
+ isStream: false,
57
+ meta: { agent: 'test' },
58
+ sections: [{ name: 'content', content }],
59
+ };
60
+ const text = await serialize(doc);
61
+ const restored = parse(text);
62
+ // Each round-trip should be identity
63
+ assert.equal(restored.sections[0].content, content, `Round ${i} failed for ${JSON.stringify(original)}`);
64
+ }
65
+ }
66
+ });
67
+ });
68
+ // ================================================================
69
+ // Parse/Serialize Round-Trip Tests
70
+ // ================================================================
71
+ describe('conformance: parse/serialize round-trip', () => {
72
+ for (const c of vectors.parse_serialize_roundtrip.cases) {
73
+ it(`[${c.desc}]`, async () => {
74
+ const doc = {
75
+ formatVersion: '1.0',
76
+ isStream: false,
77
+ meta: c.meta,
78
+ sections: c.sections.map((s) => ({
79
+ name: s.name,
80
+ content: s.content,
81
+ })),
82
+ };
83
+ const text = await serialize(doc);
84
+ const restored = parse(text);
85
+ assert.equal(restored.sections.length, doc.sections.length, `Section count mismatch`);
86
+ for (let i = 0; i < doc.sections.length; i++) {
87
+ assert.equal(restored.sections[i].name, doc.sections[i].name, `Name mismatch at ${i}`);
88
+ assert.equal(restored.sections[i].content, doc.sections[i].content, `Content mismatch in '${doc.sections[i].name}'`);
89
+ }
90
+ });
91
+ }
92
+ });
93
+ // ================================================================
94
+ // Checksum Tests
95
+ // ================================================================
96
+ describe('conformance: checksum', () => {
97
+ for (const c of vectors.checksum.cases) {
98
+ it(`[${c.desc}]`, async () => {
99
+ const sections = c.sections.map((s) => ({
100
+ name: s.name,
101
+ content: s.content,
102
+ }));
103
+ const hash = await computeChecksum(sections);
104
+ assert.equal(hash, c.expected_checksum, `Checksum mismatch`);
105
+ });
106
+ }
107
+ });
108
+ // ================================================================
109
+ // Adversarial Tests
110
+ // ================================================================
111
+ describe('conformance: adversarial', () => {
112
+ it('content with all PFM markers survives round-trip', async () => {
113
+ const dangerous = 'Line before\n#@fake-section\n#!PFM/1.0\n#!END\n\\#@escaped\n\\\\#@double\nLine after';
114
+ const doc = {
115
+ formatVersion: '1.0',
116
+ isStream: false,
117
+ meta: { agent: 'test' },
118
+ sections: [{ name: 'content', content: dangerous }],
119
+ };
120
+ const text = await serialize(doc);
121
+ const restored = parse(text);
122
+ assert.equal(restored.sections[0].content, dangerous);
123
+ });
124
+ it('unicode content round-trips', async () => {
125
+ const content = 'Hello 世界 🌍 مرحبا Ñoño → résumé';
126
+ const doc = {
127
+ formatVersion: '1.0',
128
+ isStream: false,
129
+ meta: { agent: 'test' },
130
+ sections: [{ name: 'content', content }],
131
+ };
132
+ const text = await serialize(doc);
133
+ const restored = parse(text);
134
+ assert.equal(restored.sections[0].content, content);
135
+ });
136
+ it('empty section round-trips', async () => {
137
+ const doc = {
138
+ formatVersion: '1.0',
139
+ isStream: false,
140
+ meta: { agent: 'test' },
141
+ sections: [
142
+ { name: 'content', content: '' },
143
+ { name: 'chain', content: 'data' },
144
+ ],
145
+ };
146
+ const text = await serialize(doc);
147
+ const restored = parse(text);
148
+ assert.equal(restored.sections[0].content, '');
149
+ assert.equal(restored.sections[1].content, 'data');
150
+ });
151
+ it('many sections round-trip', async () => {
152
+ const sections = Array.from({ length: 50 }, (_, i) => ({
153
+ name: `section${String(i).padStart(3, '0')}`,
154
+ content: `content-${i}`,
155
+ }));
156
+ const doc = {
157
+ formatVersion: '1.0',
158
+ isStream: false,
159
+ meta: { agent: 'test' },
160
+ sections,
161
+ };
162
+ const text = await serialize(doc);
163
+ const restored = parse(text);
164
+ assert.equal(restored.sections.length, 50);
165
+ for (let i = 0; i < 50; i++) {
166
+ assert.equal(restored.sections[i].content, `content-${i}`);
167
+ }
168
+ });
169
+ });
170
+ //# sourceMappingURL=conformance.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance.test.js","sourceRoot":"","sources":["../../../src/__tests__/conformance.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * PFM npm package tests — uses Node.js built-in test runner.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/index.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,287 @@
1
+ /**
2
+ * PFM npm package tests — uses Node.js built-in test runner.
3
+ */
4
+ import { describe, it } from 'node:test';
5
+ import assert from 'node:assert/strict';
6
+ import { parse, isPFM, getSection, getSections, computeChecksum, validateChecksum, toJSON, fromJSON, toMarkdown, serialize, META_FIELDS, SECTION_TYPES, } from '../index.js';
7
+ const EXAMPLE_PFM = `#!PFM/1.0
8
+ #@meta
9
+ id: abc-123
10
+ agent: test-agent
11
+ model: test-model
12
+ created: 2026-01-01T00:00:00Z
13
+ checksum: placeholder
14
+ tags: test,demo
15
+ version: 1.0
16
+ #@index
17
+ content 200 13
18
+ chain 220 10
19
+ #@content
20
+ Hello, world!
21
+ #@chain
22
+ Some chain
23
+ #!END
24
+ `;
25
+ // ================================================================
26
+ // Parser
27
+ // ================================================================
28
+ describe('parse', () => {
29
+ it('parses magic line and format version', () => {
30
+ const doc = parse(EXAMPLE_PFM);
31
+ assert.equal(doc.formatVersion, '1.0');
32
+ assert.equal(doc.isStream, false);
33
+ });
34
+ it('parses metadata fields', () => {
35
+ const doc = parse(EXAMPLE_PFM);
36
+ assert.equal(doc.meta.id, 'abc-123');
37
+ assert.equal(doc.meta.agent, 'test-agent');
38
+ assert.equal(doc.meta.model, 'test-model');
39
+ assert.equal(doc.meta.tags, 'test,demo');
40
+ });
41
+ it('parses sections in order', () => {
42
+ const doc = parse(EXAMPLE_PFM);
43
+ assert.equal(doc.sections.length, 2);
44
+ assert.equal(doc.sections[0].name, 'content');
45
+ assert.equal(doc.sections[0].content, 'Hello, world!');
46
+ assert.equal(doc.sections[1].name, 'chain');
47
+ assert.equal(doc.sections[1].content, 'Some chain');
48
+ });
49
+ it('handles stream mode flag', () => {
50
+ const stream = '#!PFM/1.0:STREAM\n#@meta\nagent: x\n#@content\nhi\n#!END\n';
51
+ const doc = parse(stream);
52
+ assert.equal(doc.isStream, true);
53
+ assert.equal(doc.formatVersion, '1.0');
54
+ });
55
+ it('unescapes content lines', () => {
56
+ const pfm = '#!PFM/1.0\n#@meta\n#@content\nline1\n\\#@fake\n\\#!END\nline4\n#!END\n';
57
+ const doc = parse(pfm);
58
+ assert.equal(doc.sections[0].content, 'line1\n#@fake\n#!END\nline4');
59
+ });
60
+ it('handles missing EOF marker', () => {
61
+ const noeof = '#!PFM/1.0\n#@meta\nagent: x\n#@content\nhello';
62
+ const doc = parse(noeof);
63
+ assert.equal(doc.sections.length, 1);
64
+ assert.equal(doc.sections[0].content, 'hello');
65
+ });
66
+ it('handles empty sections', () => {
67
+ const pfm = '#!PFM/1.0\n#@meta\n#@content\n#@chain\ndata\n#!END\n';
68
+ const doc = parse(pfm);
69
+ assert.equal(doc.sections.length, 2);
70
+ assert.equal(doc.sections[0].name, 'content');
71
+ assert.equal(doc.sections[0].content, '');
72
+ assert.equal(doc.sections[1].content, 'data');
73
+ });
74
+ it('handles multiline content', () => {
75
+ const pfm = '#!PFM/1.0\n#@meta\n#@content\nline1\nline2\nline3\n#!END\n';
76
+ const doc = parse(pfm);
77
+ assert.equal(doc.sections[0].content, 'line1\nline2\nline3');
78
+ });
79
+ it('handles custom meta fields', () => {
80
+ const pfm = '#!PFM/1.0\n#@meta\nagent: x\ncustom_field: custom_value\n#@content\nhi\n#!END\n';
81
+ const doc = parse(pfm);
82
+ assert.equal(doc.meta.custom_field, 'custom_value');
83
+ });
84
+ });
85
+ // ================================================================
86
+ // isPFM
87
+ // ================================================================
88
+ describe('isPFM', () => {
89
+ it('returns true for PFM text', () => {
90
+ assert.equal(isPFM('#!PFM/1.0\n'), true);
91
+ assert.equal(isPFM('#!PFM/1.0:STREAM\n'), true);
92
+ });
93
+ it('returns false for non-PFM text', () => {
94
+ assert.equal(isPFM('not a pfm file'), false);
95
+ assert.equal(isPFM(''), false);
96
+ assert.equal(isPFM('{"json": true}'), false);
97
+ });
98
+ });
99
+ // ================================================================
100
+ // getSection / getSections
101
+ // ================================================================
102
+ describe('getSection', () => {
103
+ const doc = parse(EXAMPLE_PFM);
104
+ it('returns section content by name', () => {
105
+ assert.equal(getSection(doc, 'content'), 'Hello, world!');
106
+ assert.equal(getSection(doc, 'chain'), 'Some chain');
107
+ });
108
+ it('returns undefined for missing section', () => {
109
+ assert.equal(getSection(doc, 'nope'), undefined);
110
+ });
111
+ });
112
+ describe('getSections', () => {
113
+ it('returns all sections with given name', () => {
114
+ const pfm = '#!PFM/1.0\n#@meta\n#@content\nfirst\n#@content\nsecond\n#!END\n';
115
+ const doc = parse(pfm);
116
+ const contents = getSections(doc, 'content');
117
+ assert.equal(contents.length, 2);
118
+ assert.equal(contents[0], 'first');
119
+ assert.equal(contents[1], 'second');
120
+ });
121
+ it('returns empty array for missing section', () => {
122
+ const doc = parse(EXAMPLE_PFM);
123
+ assert.deepEqual(getSections(doc, 'nope'), []);
124
+ });
125
+ });
126
+ // ================================================================
127
+ // Checksum
128
+ // ================================================================
129
+ describe('computeChecksum', () => {
130
+ it('returns hex SHA-256 digest', async () => {
131
+ const hash = await computeChecksum([{ name: 'content', content: 'hello' }]);
132
+ assert.equal(typeof hash, 'string');
133
+ assert.equal(hash.length, 64);
134
+ assert.match(hash, /^[0-9a-f]{64}$/);
135
+ });
136
+ it('is deterministic', async () => {
137
+ const sections = [{ name: 'a', content: 'test' }];
138
+ const h1 = await computeChecksum(sections);
139
+ const h2 = await computeChecksum(sections);
140
+ assert.equal(h1, h2);
141
+ });
142
+ it('changes with different content', async () => {
143
+ const h1 = await computeChecksum([{ name: 'a', content: 'hello' }]);
144
+ const h2 = await computeChecksum([{ name: 'a', content: 'world' }]);
145
+ assert.notEqual(h1, h2);
146
+ });
147
+ });
148
+ describe('validateChecksum', () => {
149
+ it('returns valid=false when no checksum in meta', async () => {
150
+ const doc = parse('#!PFM/1.0\n#@meta\nagent: x\n#@content\nhi\n#!END\n');
151
+ const result = await validateChecksum(doc);
152
+ assert.equal(result.valid, false);
153
+ });
154
+ it('validates a correct checksum', async () => {
155
+ // First compute what the checksum should be
156
+ const hash = await computeChecksum([{ name: 'content', content: 'hi' }]);
157
+ const pfm = `#!PFM/1.0\n#@meta\nchecksum: ${hash}\n#@content\nhi\n#!END\n`;
158
+ const doc = parse(pfm);
159
+ const result = await validateChecksum(doc);
160
+ assert.equal(result.valid, true);
161
+ assert.equal(result.expected, hash);
162
+ assert.equal(result.computed, hash);
163
+ });
164
+ it('rejects incorrect checksum', async () => {
165
+ const pfm = '#!PFM/1.0\n#@meta\nchecksum: deadbeef\n#@content\nhi\n#!END\n';
166
+ const doc = parse(pfm);
167
+ const result = await validateChecksum(doc);
168
+ assert.equal(result.valid, false);
169
+ assert.equal(result.expected, 'deadbeef');
170
+ assert.notEqual(result.computed, 'deadbeef');
171
+ });
172
+ });
173
+ // ================================================================
174
+ // Converters
175
+ // ================================================================
176
+ describe('toJSON / fromJSON', () => {
177
+ it('round-trips through JSON', () => {
178
+ const doc = parse(EXAMPLE_PFM);
179
+ const json = toJSON(doc);
180
+ const parsed = JSON.parse(json);
181
+ assert.equal(parsed.pfm_version, '1.0');
182
+ assert.equal(parsed.meta.agent, 'test-agent');
183
+ assert.equal(parsed.sections.length, 2);
184
+ assert.equal(parsed.sections[0].name, 'content');
185
+ });
186
+ it('fromJSON restores document structure', () => {
187
+ const doc = parse(EXAMPLE_PFM);
188
+ const json = toJSON(doc);
189
+ const restored = fromJSON(json);
190
+ assert.equal(restored.formatVersion, '1.0');
191
+ assert.equal(restored.meta.agent, 'test-agent');
192
+ assert.equal(restored.sections.length, 2);
193
+ assert.equal(restored.sections[0].content, 'Hello, world!');
194
+ });
195
+ });
196
+ describe('toMarkdown', () => {
197
+ it('produces markdown with frontmatter', () => {
198
+ const doc = parse(EXAMPLE_PFM);
199
+ const md = toMarkdown(doc);
200
+ assert.ok(md.startsWith('---\n'));
201
+ assert.ok(md.includes('agent: test-agent'));
202
+ assert.ok(md.includes('## content'));
203
+ assert.ok(md.includes('Hello, world!'));
204
+ assert.ok(md.includes('## chain'));
205
+ });
206
+ });
207
+ // ================================================================
208
+ // Serialize
209
+ // ================================================================
210
+ describe('serialize', () => {
211
+ it('produces valid PFM text', async () => {
212
+ const doc = {
213
+ formatVersion: '1.0',
214
+ isStream: false,
215
+ meta: { agent: 'test', model: 'test-model' },
216
+ sections: [{ name: 'content', content: 'Hello!' }],
217
+ };
218
+ const text = await serialize(doc);
219
+ assert.ok(text.startsWith('#!PFM/1.0\n'));
220
+ assert.ok(text.includes('#@meta\n'));
221
+ assert.ok(text.includes('agent: test\n'));
222
+ assert.ok(text.includes('#@content\n'));
223
+ assert.ok(text.includes('Hello!\n'));
224
+ assert.ok(text.includes('#!END\n'));
225
+ assert.ok(text.includes('#@index\n'));
226
+ });
227
+ it('round-trips parse -> serialize -> parse', async () => {
228
+ const original = {
229
+ formatVersion: '1.0',
230
+ isStream: false,
231
+ meta: { agent: 'roundtrip', model: 'gpt-4' },
232
+ sections: [
233
+ { name: 'content', content: 'Line one\nLine two' },
234
+ { name: 'chain', content: 'User: hello\nAgent: hi' },
235
+ ],
236
+ };
237
+ const text = await serialize(original);
238
+ const restored = parse(text);
239
+ assert.equal(restored.meta.agent, 'roundtrip');
240
+ assert.equal(restored.sections.length, 2);
241
+ assert.equal(restored.sections[0].content, 'Line one\nLine two');
242
+ assert.equal(restored.sections[1].content, 'User: hello\nAgent: hi');
243
+ });
244
+ it('serialized checksum validates', async () => {
245
+ const doc = {
246
+ formatVersion: '1.0',
247
+ isStream: false,
248
+ meta: { agent: 'test' },
249
+ sections: [{ name: 'content', content: 'Check me' }],
250
+ };
251
+ const text = await serialize(doc);
252
+ const parsed = parse(text);
253
+ const result = await validateChecksum(parsed);
254
+ assert.equal(result.valid, true);
255
+ });
256
+ it('escapes dangerous content lines', async () => {
257
+ const doc = {
258
+ formatVersion: '1.0',
259
+ isStream: false,
260
+ meta: {},
261
+ sections: [{ name: 'content', content: '#@fake\n#!END\nnormal line' }],
262
+ };
263
+ const text = await serialize(doc);
264
+ assert.ok(text.includes('\\#@fake'));
265
+ assert.ok(text.includes('\\#!END'));
266
+ // Verify round-trip preserves the dangerous content
267
+ const parsed = parse(text);
268
+ assert.equal(parsed.sections[0].content, '#@fake\n#!END\nnormal line');
269
+ });
270
+ });
271
+ // ================================================================
272
+ // Constants
273
+ // ================================================================
274
+ describe('constants', () => {
275
+ it('META_FIELDS has standard keys', () => {
276
+ assert.ok('id' in META_FIELDS);
277
+ assert.ok('agent' in META_FIELDS);
278
+ assert.ok('checksum' in META_FIELDS);
279
+ });
280
+ it('SECTION_TYPES has standard sections', () => {
281
+ assert.ok('content' in SECTION_TYPES);
282
+ assert.ok('chain' in SECTION_TYPES);
283
+ assert.ok('tools' in SECTION_TYPES);
284
+ assert.ok('metrics' in SECTION_TYPES);
285
+ });
286
+ });
287
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/__tests__/index.test.ts"],"names":[],"mappings":"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"}