dcp-wrap 0.2.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.
package/README.md ADDED
@@ -0,0 +1,172 @@
1
+ # dcp-wrap
2
+
3
+ Convert JSON to [DCP](https://dcp-docs.pages.dev) positional-array format — fewer tokens, same accuracy.
4
+
5
+ ## What it does
6
+
7
+ DCP strips repeated keys from structured data. Instead of sending `{"endpoint":"/v1/users","method":"GET","status":200}` per record, DCP declares the schema once and writes values by position:
8
+
9
+ ```
10
+ ["$S","api-response:v1","endpoint","method","status","latency_ms"]
11
+ ["/v1/users","GET",200,42]
12
+ ["/v1/orders","POST",201,187]
13
+ ```
14
+
15
+ 40–60% token reduction when feeding data to LLMs. Zero accuracy cost. See [benchmark](https://dcp-docs.pages.dev/dcp/specification#benchmark-dcp-vs-json-vs-natural-language).
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install dcp-wrap
21
+ ```
22
+
23
+ Or use directly:
24
+
25
+ ```bash
26
+ npx dcp-wrap
27
+ ```
28
+
29
+ ## CLI
30
+
31
+ ### Infer schema from JSON
32
+
33
+ ```bash
34
+ cat api-response.json | npx dcp-wrap init api-response
35
+ ```
36
+
37
+ Output:
38
+ ```
39
+ Schema: api-response:v1
40
+ Fields: 4
41
+
42
+ endpoint: string (source: endpoint, unique: 4/4)
43
+ method: string (source: method, unique: 2/4) [enum(2)]
44
+ status: number (source: status, unique: 2/4)
45
+ latency_ms: number (source: latency_ms, unique: 4/4)
46
+
47
+ Saved: dcp-schemas/api-response.v1.json
48
+ Saved: dcp-schemas/api-response.v1.mapping.json
49
+ ```
50
+
51
+ The generator infers field types, detects enums, numeric ranges, and orders fields by DCP convention (identifiers → classifiers → numerics → text).
52
+
53
+ ### Encode JSON to DCP
54
+
55
+ ```bash
56
+ cat data.json | npx dcp-wrap encode --schema dcp-schemas/api-response.v1.json
57
+ ```
58
+
59
+ Output:
60
+ ```
61
+ ["$S","api-response:v1","endpoint","method","status","latency_ms"]
62
+ ["/v1/users","GET",200,42]
63
+ ["/v1/orders","POST",201,187]
64
+ ["/v1/auth","POST",200,95]
65
+ ```
66
+
67
+ ### Inspect a schema
68
+
69
+ ```bash
70
+ npx dcp-wrap inspect dcp-schemas/api-response.v1.json
71
+ ```
72
+
73
+ ## Programmatic API
74
+
75
+ ### Quick — one function, no files
76
+
77
+ For known structures where you define the schema inline:
78
+
79
+ ```typescript
80
+ import { dcpEncode } from "dcp-wrap";
81
+
82
+ const dcp = dcpEncode(results, {
83
+ id: "engram-recall:v1",
84
+ fields: ["id", "relevance", "summary", "tags", "hitCount", "weight", "status"],
85
+ });
86
+ // ["$S","engram-recall:v1","id","relevance","summary","tags","hitCount","weight","status"]
87
+ // ["abc123",0.95,"port conflict fix","docker,gotcha",12,3.2,"fixed"]
88
+ ```
89
+
90
+ Array fields are auto-joined with comma. Use `transform` for custom handling:
91
+
92
+ ```typescript
93
+ const dcp = dcpEncode(records, schema, {
94
+ transform: { relevance: (v) => +(v as number).toFixed(3) },
95
+ });
96
+ ```
97
+
98
+ ### Full — schema generation + encoding
99
+
100
+ For unknown JSON where you want schema inference:
101
+
102
+ ```typescript
103
+ import { SchemaGenerator, DcpEncoder, DcpSchema, FieldMapping } from "dcp-wrap";
104
+
105
+ const gen = new SchemaGenerator();
106
+ const draft = gen.fromSamples(jsonRecords, { domain: "github-pr" });
107
+
108
+ const schema = new DcpSchema(draft.schema);
109
+ const mapping = new FieldMapping(draft.mapping);
110
+ const encoder = new DcpEncoder(schema, mapping);
111
+
112
+ const batch = encoder.encode(jsonRecords);
113
+ console.log(DcpEncoder.toString(batch));
114
+ ```
115
+
116
+ ## Nested JSON
117
+
118
+ Nested objects are automatically flattened via dot-notation:
119
+
120
+ ```json
121
+ {"id": "pr-1", "metadata": {"author": "alice", "state": "open"}}
122
+ ```
123
+
124
+ The generator maps `metadata.author` → `author`, `metadata.state` → `state`. The mapping file records the full paths for encoding.
125
+
126
+ ## Working with messy data
127
+
128
+ Real-world APIs return deeply nested objects, inconsistent fields, and dozens of keys you don't need. The generator applies three guards by default:
129
+
130
+ | Guard | Default | What it does |
131
+ |-------|---------|-------------|
132
+ | `maxDepth` | 3 | Stops flattening at 3 levels. `a.b.c` is resolved; `a.b.c.d.e` is kept as an opaque value. |
133
+ | `maxFields` | 20 | Keeps the top 20 fields by DCP priority (identifiers → classifiers → numerics → text). The rest are dropped. |
134
+ | `minPresence` | 0.1 | Fields appearing in less than 10% of samples are excluded. |
135
+
136
+ Override when needed:
137
+
138
+ ```typescript
139
+ const draft = gen.fromSamples(samples, {
140
+ domain: "some-api",
141
+ maxDepth: 2, // very flat — only top-level and one level of nesting
142
+ maxFields: 10, // aggressive trim
143
+ minPresence: 0.5, // field must appear in at least half the samples
144
+ });
145
+ ```
146
+
147
+ **Always review the generated schema before using it in production.** The generator infers — it does not know your intent. Check:
148
+
149
+ - Are the right fields included? Use `include` / `exclude` to override.
150
+ - Are field names sensible? Nested paths become leaf names (`metadata.author` → `author`). Use `fieldNames` to rename.
151
+ - Are array fields handled correctly? Arrays are auto-joined with comma in `dcpEncode()`. Use `transform` for custom serialization.
152
+ - Is the schema ID correct? The generator derives `{domain}:v{version}` from your input. This ID is how consumers identify the schema.
153
+
154
+ ## Design
155
+
156
+ - **Zero runtime dependencies**
157
+ - Schema generation follows DCP field ordering convention
158
+ - Supports JSON arrays and newline-delimited JSON (NDJSON) as input
159
+ - Handles nested objects, enum detection, nullable fields, numeric ranges
160
+ - Schema + mapping files are plain JSON — review, version, and edit them
161
+
162
+ dcp-wrap handles JSON → DCP conversion. For shadow index optimization, agent profiling, and the full protocol design, see [dcp-docs.pages.dev](https://dcp-docs.pages.dev).
163
+
164
+ ## PicoClaw Integration
165
+
166
+ dcp-wrap ships with an out-of-process hook for [PicoClaw](https://github.com/sipeed/picoclaw) that DCP-encodes tool results before they reach the LLM. No core modification needed — just configure a process hook.
167
+
168
+ See [docs/picoclaw-integration.md](docs/picoclaw-integration.md) for setup guide, Docker instructions, and gotchas.
169
+
170
+ ## License
171
+
172
+ Apache-2.0
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { SchemaGenerator, formatReport } from "./generator.js";
5
+ import { DcpSchema } from "./schema.js";
6
+ import { FieldMapping } from "./mapping.js";
7
+ import { DcpEncoder } from "./encoder.js";
8
+ function readStdinSync() {
9
+ try {
10
+ return readFileSync(0, "utf-8");
11
+ }
12
+ catch {
13
+ return "";
14
+ }
15
+ }
16
+ function readInput(args) {
17
+ const samplesIdx = args.indexOf("--samples");
18
+ const inputIdx = args.indexOf("--input");
19
+ const fileIdx = samplesIdx !== -1 ? samplesIdx : inputIdx;
20
+ let raw;
21
+ if (fileIdx !== -1 && args[fileIdx + 1]) {
22
+ raw = readFileSync(args[fileIdx + 1], "utf-8");
23
+ }
24
+ else {
25
+ raw = readStdinSync();
26
+ }
27
+ if (!raw.trim()) {
28
+ console.error("Error: no input data. Pipe JSON or use --samples <file>");
29
+ process.exit(1);
30
+ }
31
+ // Try JSON array first, then newline-delimited JSON
32
+ const trimmed = raw.trim();
33
+ if (trimmed.startsWith("[")) {
34
+ const parsed = JSON.parse(trimmed);
35
+ if (Array.isArray(parsed) && parsed.length > 0 && typeof parsed[0] === "object") {
36
+ return parsed;
37
+ }
38
+ }
39
+ // NDJSON
40
+ const lines = trimmed.split("\n").filter((l) => l.trim());
41
+ return lines.map((l) => JSON.parse(l));
42
+ }
43
+ function cmdInit(args) {
44
+ const domain = args[0];
45
+ if (!domain) {
46
+ console.error("Usage: dcp-wrap init <domain> [--samples file.json]");
47
+ console.error(" e.g.: cat data.json | dcp-wrap init github-pr");
48
+ process.exit(1);
49
+ }
50
+ const samples = readInput(args.slice(1));
51
+ const gen = new SchemaGenerator();
52
+ const draft = gen.fromSamples(samples, { domain });
53
+ // Print report to stderr
54
+ console.error(formatReport(draft));
55
+ console.error("");
56
+ // Save schema
57
+ const outDir = "dcp-schemas";
58
+ const schemaPath = join(outDir, `${domain}.v1.json`);
59
+ const mappingPath = join(outDir, `${domain}.v1.mapping.json`);
60
+ mkdirSync(outDir, { recursive: true });
61
+ writeFileSync(schemaPath, JSON.stringify(draft.schema, null, 2) + "\n", "utf-8");
62
+ writeFileSync(mappingPath, JSON.stringify(draft.mapping, null, 2) + "\n", "utf-8");
63
+ console.error(`Saved: ${schemaPath}`);
64
+ console.error(`Saved: ${mappingPath}`);
65
+ // Print schema to stdout
66
+ console.log(JSON.stringify(draft.schema, null, 2));
67
+ }
68
+ function cmdEncode(args) {
69
+ const schemaIdx = args.indexOf("--schema");
70
+ if (schemaIdx === -1 || !args[schemaIdx + 1]) {
71
+ console.error("Usage: dcp-wrap encode --schema <schema.json> [--input file.json]");
72
+ process.exit(1);
73
+ }
74
+ const schemaPath = args[schemaIdx + 1];
75
+ const schema = DcpSchema.fromFile(schemaPath);
76
+ // Try to load mapping from adjacent file
77
+ const mappingPath = schemaPath.replace(".json", ".mapping.json");
78
+ let mapping;
79
+ try {
80
+ const mappingDef = JSON.parse(readFileSync(mappingPath, "utf-8"));
81
+ mapping = new FieldMapping(mappingDef);
82
+ }
83
+ catch {
84
+ // Auto-bind: assume field names match source keys
85
+ const paths = {};
86
+ for (const f of schema.fields)
87
+ paths[f] = f;
88
+ mapping = new FieldMapping({ schemaId: schema.id, paths });
89
+ }
90
+ const records = readInput(args);
91
+ const encoder = new DcpEncoder(schema, mapping);
92
+ const batch = encoder.encode(records);
93
+ console.log(DcpEncoder.toString(batch));
94
+ }
95
+ function cmdInspect(args) {
96
+ const schemaPath = args[0];
97
+ if (!schemaPath) {
98
+ console.error("Usage: dcp-wrap inspect <schema.json>");
99
+ process.exit(1);
100
+ }
101
+ const schema = DcpSchema.fromFile(schemaPath);
102
+ console.log(`Schema: ${schema.id}`);
103
+ console.log(`Fields: ${schema.fieldCount}`);
104
+ console.log(`Header: ${JSON.stringify(schema.sHeader())}`);
105
+ console.log("");
106
+ for (let i = 0; i < schema.fields.length; i++) {
107
+ const f = schema.fields[i];
108
+ const t = schema.types[f];
109
+ const typeStr = t
110
+ ? Array.isArray(t.type) ? t.type.join("|") : t.type
111
+ : "unknown";
112
+ const extras = [];
113
+ if (t?.enum)
114
+ extras.push(`enum: ${JSON.stringify(t.enum)}`);
115
+ if (t?.min != null)
116
+ extras.push(`min: ${t.min}`);
117
+ if (t?.max != null)
118
+ extras.push(`max: ${t.max}`);
119
+ const extStr = extras.length > 0 ? ` (${extras.join(", ")})` : "";
120
+ console.log(` [${i}] ${f}: ${typeStr}${extStr}`);
121
+ }
122
+ }
123
+ // ── Main ───────────────────────────────────────────────────
124
+ const args = process.argv.slice(2);
125
+ const command = args[0];
126
+ switch (command) {
127
+ case "init":
128
+ cmdInit(args.slice(1));
129
+ break;
130
+ case "encode":
131
+ cmdEncode(args.slice(1));
132
+ break;
133
+ case "inspect":
134
+ cmdInspect(args.slice(1));
135
+ break;
136
+ default:
137
+ console.error("dcp-wrap — Convert JSON to DCP positional-array format");
138
+ console.error("");
139
+ console.error("Commands:");
140
+ console.error(" init <domain> [--samples file.json] Infer schema from JSON samples");
141
+ console.error(" encode --schema <file> [--input file] Encode JSON to DCP");
142
+ console.error(" inspect <schema.json> Show schema details");
143
+ console.error("");
144
+ console.error("Examples:");
145
+ console.error(" cat api-response.json | dcp-wrap init github-pr");
146
+ console.error(" cat data.json | dcp-wrap encode --schema dcp-schemas/github-pr.v1.json");
147
+ console.error("");
148
+ console.error("Learn more: https://dcp-docs.pages.dev");
149
+ process.exit(command ? 1 : 0);
150
+ }
151
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { DcpSchema } from "./schema.js";
2
+ /** Result of decoding a single DCP row. */
3
+ export interface DecodeResult {
4
+ keyValues: Record<string, unknown>;
5
+ text: string;
6
+ }
7
+ /** Template map: key (e.g. enum value or "default") → template string with {{field}} placeholders. */
8
+ export type TemplateMap = Record<string, string>;
9
+ export declare class DcpDecoder {
10
+ private readonly schema;
11
+ private readonly templates;
12
+ private readonly templateField;
13
+ /**
14
+ * @param schema - DcpSchema instance
15
+ * @param templates - Optional templates keyed by enum value or "default".
16
+ * Use {{fieldName}} for interpolation.
17
+ * @param templateField - Field name whose value selects the template (typically an enum field).
18
+ * If omitted, auto-detects first enum field.
19
+ */
20
+ constructor(schema: DcpSchema, templates?: TemplateMap, templateField?: string);
21
+ /** Decode a positional array into key-values and human-readable text. */
22
+ decode(row: unknown[], mask?: number): DecodeResult;
23
+ /** Decode multiple rows. */
24
+ decodeRows(rows: unknown[][], mask?: number): DecodeResult[];
25
+ /**
26
+ * Parse a raw DCP string (header + rows) and decode all rows.
27
+ * Handles $S header line, returns decoded results.
28
+ */
29
+ decodeRaw(raw: string): {
30
+ header: unknown[];
31
+ results: DecodeResult[];
32
+ };
33
+ private renderTemplate;
34
+ private detectEnumField;
35
+ }
@@ -0,0 +1,95 @@
1
+ export class DcpDecoder {
2
+ schema;
3
+ templates;
4
+ templateField;
5
+ /**
6
+ * @param schema - DcpSchema instance
7
+ * @param templates - Optional templates keyed by enum value or "default".
8
+ * Use {{fieldName}} for interpolation.
9
+ * @param templateField - Field name whose value selects the template (typically an enum field).
10
+ * If omitted, auto-detects first enum field.
11
+ */
12
+ constructor(schema, templates, templateField) {
13
+ this.schema = schema;
14
+ this.templates = templates ?? {};
15
+ this.templateField = templateField ?? this.detectEnumField();
16
+ }
17
+ /** Decode a positional array into key-values and human-readable text. */
18
+ decode(row, mask) {
19
+ const fields = mask != null
20
+ ? this.schema.fieldsFromMask(mask)
21
+ : this.schema.fields;
22
+ const keyValues = {};
23
+ for (let i = 0; i < fields.length; i++) {
24
+ keyValues[fields[i]] = i < row.length ? row[i] : null;
25
+ }
26
+ const text = this.renderTemplate(keyValues);
27
+ return { keyValues, text };
28
+ }
29
+ /** Decode multiple rows. */
30
+ decodeRows(rows, mask) {
31
+ return rows.map((row) => this.decode(row, mask));
32
+ }
33
+ /**
34
+ * Parse a raw DCP string (header + rows) and decode all rows.
35
+ * Handles $S header line, returns decoded results.
36
+ */
37
+ decodeRaw(raw) {
38
+ const lines = raw
39
+ .split("\n")
40
+ .map((l) => l.trim())
41
+ .filter((l) => l.length > 0);
42
+ if (lines.length === 0)
43
+ return { header: [], results: [] };
44
+ let headerLine = [];
45
+ let dataLines = lines;
46
+ // Check if first line is a $S header
47
+ const first = JSON.parse(lines[0]);
48
+ if (Array.isArray(first) && first[0] === "$S") {
49
+ headerLine = first;
50
+ dataLines = lines.slice(1);
51
+ }
52
+ const results = dataLines.map((line) => {
53
+ const row = JSON.parse(line);
54
+ return this.decode(row);
55
+ });
56
+ return { header: headerLine, results };
57
+ }
58
+ renderTemplate(kv) {
59
+ // Try value-specific template
60
+ if (this.templateField && this.templates) {
61
+ const val = kv[this.templateField];
62
+ if (typeof val === "string" && this.templates[val]) {
63
+ return interpolate(this.templates[val], kv);
64
+ }
65
+ }
66
+ // Try default template
67
+ if (this.templates?.["default"]) {
68
+ return interpolate(this.templates["default"], kv);
69
+ }
70
+ // Fallback: field: value pairs
71
+ return this.schema.fields
72
+ .map((f) => {
73
+ const v = kv[f];
74
+ return v !== null && v !== undefined ? `${f}: ${v}` : null;
75
+ })
76
+ .filter(Boolean)
77
+ .join(" | ");
78
+ }
79
+ detectEnumField() {
80
+ for (const f of this.schema.fields) {
81
+ const ft = this.schema.types[f];
82
+ if (ft?.enum && ft.enum.length > 0)
83
+ return f;
84
+ }
85
+ return null;
86
+ }
87
+ }
88
+ /** Replace {{field}} placeholders. Nulls become empty string. */
89
+ function interpolate(template, kv) {
90
+ return template.replace(/\{\{(\w+)\}\}/g, (_, key) => {
91
+ const val = kv[key];
92
+ return val !== null && val !== undefined ? String(val) : "";
93
+ });
94
+ }
95
+ //# sourceMappingURL=decoder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoder.js","sourceRoot":"","sources":["../src/decoder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,144 @@
1
+ import { describe, it } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { DcpSchema } from "./schema.js";
4
+ import { DcpDecoder } from "./decoder.js";
5
+ const reportDef = {
6
+ $dcp: "schema",
7
+ id: "ctrl-report:v1",
8
+ description: "Task completion report controller",
9
+ fields: ["action", "target", "detail", "cost"],
10
+ fieldCount: 4,
11
+ types: {
12
+ action: { type: "string", enum: ["done", "error", "skip", "partial"] },
13
+ target: { type: "string" },
14
+ detail: { type: ["string", "null"] },
15
+ cost: { type: ["number", "null"] },
16
+ },
17
+ };
18
+ const reportTemplates = {
19
+ done: "✓ {{target}} — {{detail}} ({{cost}}ms)",
20
+ error: "✗ {{target}} — {{detail}}",
21
+ skip: "⊘ {{target}} skipped",
22
+ partial: "◐ {{target}} — {{detail}}",
23
+ default: "{{action}} {{target}} {{detail}}",
24
+ };
25
+ const logDef = {
26
+ $dcp: "schema",
27
+ id: "ctrl-log:v1",
28
+ description: "Event log controller",
29
+ fields: ["ts", "level", "source", "msg"],
30
+ fieldCount: 4,
31
+ types: {
32
+ ts: { type: "string" },
33
+ level: { type: "string", enum: ["info", "warn", "error", "debug"] },
34
+ source: { type: "string" },
35
+ msg: { type: "string" },
36
+ },
37
+ };
38
+ const logTemplates = {
39
+ error: "[{{ts}}] ERROR {{source}}: {{msg}}",
40
+ warn: "[{{ts}}] WARN {{source}}: {{msg}}",
41
+ info: "[{{ts}}] INFO {{source}}: {{msg}}",
42
+ default: "[{{ts}}] {{level}} {{source}}: {{msg}}",
43
+ };
44
+ describe("DcpDecoder", () => {
45
+ describe("decode", () => {
46
+ it("decodes report:done with template", () => {
47
+ const schema = new DcpSchema(reportDef);
48
+ const decoder = new DcpDecoder(schema, reportTemplates);
49
+ const result = decoder.decode(["done", "/v1/auth", "200 ok", 42]);
50
+ assert.deepEqual(result.keyValues, {
51
+ action: "done",
52
+ target: "/v1/auth",
53
+ detail: "200 ok",
54
+ cost: 42,
55
+ });
56
+ assert.equal(result.text, "✓ /v1/auth — 200 ok (42ms)");
57
+ });
58
+ it("decodes report:error", () => {
59
+ const schema = new DcpSchema(reportDef);
60
+ const decoder = new DcpDecoder(schema, reportTemplates);
61
+ const result = decoder.decode(["error", "/v1/orders", "timeout", 0]);
62
+ assert.equal(result.text, "✗ /v1/orders — timeout");
63
+ });
64
+ it("decodes report:skip with nulls", () => {
65
+ const schema = new DcpSchema(reportDef);
66
+ const decoder = new DcpDecoder(schema, reportTemplates);
67
+ const result = decoder.decode(["skip", "cleanup", null, null]);
68
+ assert.equal(result.text, "⊘ cleanup skipped");
69
+ });
70
+ it("decodes log row with level-specific template", () => {
71
+ const schema = new DcpSchema(logDef);
72
+ const decoder = new DcpDecoder(schema, logTemplates, "level");
73
+ const result = decoder.decode([
74
+ "2026-03-28T14:30:00Z",
75
+ "error",
76
+ "db-writer",
77
+ "connection refused",
78
+ ]);
79
+ assert.equal(result.text, "[2026-03-28T14:30:00Z] ERROR db-writer: connection refused");
80
+ });
81
+ it("falls back to field:value when no templates", () => {
82
+ const schema = new DcpSchema(reportDef);
83
+ const decoder = new DcpDecoder(schema);
84
+ const result = decoder.decode(["done", "/v1/auth", "ok", 42]);
85
+ assert.equal(result.text, "action: done | target: /v1/auth | detail: ok | cost: 42");
86
+ });
87
+ });
88
+ describe("decodeRows", () => {
89
+ it("decodes multiple rows", () => {
90
+ const schema = new DcpSchema(reportDef);
91
+ const decoder = new DcpDecoder(schema, reportTemplates);
92
+ const results = decoder.decodeRows([
93
+ ["done", "/v1/auth", "200 ok", 42],
94
+ ["error", "/v1/orders", "timeout", 0],
95
+ ]);
96
+ assert.equal(results.length, 2);
97
+ assert.ok(results[0].text.includes("/v1/auth"));
98
+ assert.ok(results[1].text.includes("/v1/orders"));
99
+ });
100
+ });
101
+ describe("decodeRaw", () => {
102
+ it("parses header + rows from raw DCP string", () => {
103
+ const schema = new DcpSchema(reportDef);
104
+ const decoder = new DcpDecoder(schema, reportTemplates);
105
+ const raw = [
106
+ '["$S","ctrl-report:v1","action","target","detail","cost"]',
107
+ '["done","/v1/auth","200 ok",42]',
108
+ '["error","/v1/orders","timeout",0]',
109
+ ].join("\n");
110
+ const { header, results } = decoder.decodeRaw(raw);
111
+ assert.equal(header[0], "$S");
112
+ assert.equal(results.length, 2);
113
+ assert.ok(results[0].text.includes("✓"));
114
+ assert.ok(results[1].text.includes("✗"));
115
+ });
116
+ it("handles rows without header", () => {
117
+ const schema = new DcpSchema(reportDef);
118
+ const decoder = new DcpDecoder(schema, reportTemplates);
119
+ const raw = '["done","/v1/auth","ok",42]';
120
+ const { header, results } = decoder.decodeRaw(raw);
121
+ assert.equal(header.length, 0);
122
+ assert.equal(results.length, 1);
123
+ });
124
+ });
125
+ describe("with DcpSchema.validateRow", () => {
126
+ it("validate + decode roundtrip", () => {
127
+ const schema = new DcpSchema(reportDef);
128
+ const decoder = new DcpDecoder(schema, reportTemplates);
129
+ const row = ["done", "/v1/auth", "200 ok", 42];
130
+ const errors = schema.validateRow(row);
131
+ assert.equal(errors.length, 0);
132
+ const result = decoder.decode(row);
133
+ assert.equal(result.text, "✓ /v1/auth — 200 ok (42ms)");
134
+ });
135
+ it("validation catches bad enum", () => {
136
+ const schema = new DcpSchema(reportDef);
137
+ const row = ["invalid", "/v1/auth", "ok", 42];
138
+ const errors = schema.validateRow(row);
139
+ assert.ok(errors.length > 0);
140
+ assert.ok(errors[0].includes("not in enum"));
141
+ });
142
+ });
143
+ });
144
+ //# sourceMappingURL=decoder.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoder.test.js","sourceRoot":"","sources":["../src/decoder.test.ts"],"names":[],"mappings":"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"}