@hol-org/cigar 0.9.4

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 (78) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +5 -0
  3. package/README.md +68 -0
  4. package/dist/client.d.ts +16 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +839 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/digest.d.ts +21 -0
  9. package/dist/digest.d.ts.map +1 -0
  10. package/dist/digest.js +406 -0
  11. package/dist/digest.js.map +1 -0
  12. package/dist/errors.d.ts +35 -0
  13. package/dist/errors.d.ts.map +1 -0
  14. package/dist/errors.js +54 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/examples/quickstart.d.ts +2 -0
  17. package/dist/examples/quickstart.d.ts.map +1 -0
  18. package/dist/examples/quickstart.js +32 -0
  19. package/dist/examples/quickstart.js.map +1 -0
  20. package/dist/examples/two-agent-observer.d.ts +9 -0
  21. package/dist/examples/two-agent-observer.d.ts.map +1 -0
  22. package/dist/examples/two-agent-observer.js +59 -0
  23. package/dist/examples/two-agent-observer.js.map +1 -0
  24. package/dist/examples/verify-shared-bundle.d.ts +2 -0
  25. package/dist/examples/verify-shared-bundle.d.ts.map +1 -0
  26. package/dist/examples/verify-shared-bundle.js +13 -0
  27. package/dist/examples/verify-shared-bundle.js.map +1 -0
  28. package/dist/generated/cigar_service_pb.d.ts +642 -0
  29. package/dist/generated/cigar_service_pb.d.ts.map +1 -0
  30. package/dist/generated/cigar_service_pb.js +55 -0
  31. package/dist/generated/cigar_service_pb.js.map +1 -0
  32. package/dist/generated/context_abi_pb.d.ts +3429 -0
  33. package/dist/generated/context_abi_pb.d.ts.map +1 -0
  34. package/dist/generated/context_abi_pb.js +1386 -0
  35. package/dist/generated/context_abi_pb.js.map +1 -0
  36. package/dist/generated/errors.d.ts +242 -0
  37. package/dist/generated/errors.d.ts.map +1 -0
  38. package/dist/generated/errors.js +38 -0
  39. package/dist/generated/errors.js.map +1 -0
  40. package/dist/generated/generated/error_codes_pb.d.ts +188 -0
  41. package/dist/generated/generated/error_codes_pb.d.ts.map +1 -0
  42. package/dist/generated/generated/error_codes_pb.js +191 -0
  43. package/dist/generated/generated/error_codes_pb.js.map +1 -0
  44. package/dist/generated/models.d.ts +472 -0
  45. package/dist/generated/models.d.ts.map +1 -0
  46. package/dist/generated/models.js +314 -0
  47. package/dist/generated/models.js.map +1 -0
  48. package/dist/generated/operations.d.ts +912 -0
  49. package/dist/generated/operations.d.ts.map +1 -0
  50. package/dist/generated/operations.js +50 -0
  51. package/dist/generated/operations.js.map +1 -0
  52. package/dist/idempotency.d.ts +3 -0
  53. package/dist/idempotency.d.ts.map +1 -0
  54. package/dist/idempotency.js +16 -0
  55. package/dist/idempotency.js.map +1 -0
  56. package/dist/index.d.ts +13 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +13 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/release.json +6 -0
  61. package/dist/types.d.ts +115 -0
  62. package/dist/types.d.ts.map +1 -0
  63. package/dist/types.js +3 -0
  64. package/dist/types.js.map +1 -0
  65. package/dist/verify-replay.d.ts +3 -0
  66. package/dist/verify-replay.d.ts.map +1 -0
  67. package/dist/verify-replay.js +391 -0
  68. package/dist/verify-replay.js.map +1 -0
  69. package/dist/verify-vectors.d.ts +3 -0
  70. package/dist/verify-vectors.d.ts.map +1 -0
  71. package/dist/verify-vectors.js +383 -0
  72. package/dist/verify-vectors.js.map +1 -0
  73. package/dist/workflow-session.d.ts +93 -0
  74. package/dist/workflow-session.d.ts.map +1 -0
  75. package/dist/workflow-session.js +550 -0
  76. package/dist/workflow-session.js.map +1 -0
  77. package/fixtures/semantic-bundle-v1.json +13 -0
  78. package/package.json +60 -0
package/dist/digest.js ADDED
@@ -0,0 +1,406 @@
1
+ import { createHash } from "node:crypto";
2
+ import { ValidationError } from "./errors.js";
3
+ const DIGEST = /^1220[0-9a-f]{64}$/u;
4
+ const LANE_ORDER = new Map([
5
+ ["rules", 0],
6
+ ["task", 1],
7
+ ["evidence", 2],
8
+ ["history", 3],
9
+ ["tools", 4],
10
+ ]);
11
+ function concatenate(parts) {
12
+ const result = new Uint8Array(parts.reduce((total, part) => total + part.length, 0));
13
+ let offset = 0;
14
+ for (const part of parts) {
15
+ result.set(part, offset);
16
+ offset += part.length;
17
+ }
18
+ return result;
19
+ }
20
+ function head(major, argument) {
21
+ if (argument < 0n || argument > 0xffffffffffffffffn)
22
+ throw new ValidationError("canonical integer exceeds u64");
23
+ const prefix = major << 5;
24
+ if (argument < 24n)
25
+ return Uint8Array.of(prefix | Number(argument));
26
+ const widths = [
27
+ [0xffn, 24, 1],
28
+ [0xffffn, 25, 2],
29
+ [0xffffffffn, 26, 4],
30
+ [0xffffffffffffffffn, 27, 8],
31
+ ];
32
+ for (const [maximum, additional, width] of widths) {
33
+ if (argument <= maximum) {
34
+ const output = new Uint8Array(width + 1);
35
+ output[0] = prefix | additional;
36
+ let remainder = argument;
37
+ for (let index = width; index > 0; index -= 1) {
38
+ output[index] = Number(remainder & 0xffn);
39
+ remainder >>= 8n;
40
+ }
41
+ return output;
42
+ }
43
+ }
44
+ throw new ValidationError("canonical integer exceeds u64");
45
+ }
46
+ /** Encode the frozen CIGAR deterministic-CBOR subset. */
47
+ export function deterministicCbor(value) {
48
+ return encodeCanonical(value, 0, { nodes: 0 });
49
+ }
50
+ function encodeCanonical(value, depth, budget) {
51
+ budget.nodes += 1;
52
+ if (depth > 64 || budget.nodes > 100_000)
53
+ throw new ValidationError("canonical value exceeds nesting or node bounds");
54
+ if (value === false)
55
+ return Uint8Array.of(0xf4);
56
+ if (value === true)
57
+ return Uint8Array.of(0xf5);
58
+ if (typeof value === "number") {
59
+ if (!Number.isSafeInteger(value))
60
+ throw new ValidationError("canonical numbers must be safe integers; use bigint for wider values");
61
+ return encodeCanonical(BigInt(value), depth, budget);
62
+ }
63
+ if (typeof value === "bigint") {
64
+ if (value < -(1n << 63n))
65
+ throw new ValidationError("canonical signed integer is below i64");
66
+ return value >= 0n ? head(0, value) : head(1, -1n - value);
67
+ }
68
+ if (typeof value === "string") {
69
+ const encoded = new TextEncoder().encode(value.normalize("NFC"));
70
+ return concatenate([head(3, BigInt(encoded.length)), encoded]);
71
+ }
72
+ if (value instanceof Uint8Array)
73
+ return concatenate([head(2, BigInt(value.length)), value]);
74
+ if (Array.isArray(value)) {
75
+ return concatenate([head(4, BigInt(value.length)), ...value.map((child) => encodeCanonical(child, depth + 1, budget))]);
76
+ }
77
+ if (typeof value !== "object" || value === null)
78
+ throw new ValidationError("null is not canonical");
79
+ const entries = Object.entries(value).map(([key, child]) => {
80
+ if (child === undefined || child === null)
81
+ throw new ValidationError("undefined and null are not canonical");
82
+ return { key: encodeCanonical(key, depth + 1, budget), child };
83
+ });
84
+ entries.sort((left, right) => Buffer.compare(left.key, right.key));
85
+ for (let index = 1; index < entries.length; index += 1) {
86
+ if (Buffer.compare(entries[index - 1]?.key ?? new Uint8Array(), entries[index]?.key ?? new Uint8Array()) === 0) {
87
+ throw new ValidationError("canonical map contains a duplicate key");
88
+ }
89
+ }
90
+ return concatenate([
91
+ head(5, BigInt(entries.length)),
92
+ ...entries.flatMap(({ key, child }) => [key, encodeCanonical(child, depth + 1, budget)]),
93
+ ]);
94
+ }
95
+ function canonicalPayload(value, depth = 0, budget = { nodes: 0 }) {
96
+ budget.nodes += 1;
97
+ if (depth > 64 || budget.nodes > 100_000)
98
+ throw new ValidationError("operation payload exceeds nesting or node bounds");
99
+ if (typeof value === "boolean" || typeof value === "string" || typeof value === "bigint" || value instanceof Uint8Array) {
100
+ return value;
101
+ }
102
+ if (typeof value === "number") {
103
+ if (!Number.isSafeInteger(value))
104
+ throw new ValidationError("payload numbers must be safe integers; use bigint for int64/uint64");
105
+ return value;
106
+ }
107
+ if (Array.isArray(value))
108
+ return value.map((child) => canonicalPayload(child, depth + 1, budget));
109
+ if (typeof value === "object" && value !== null) {
110
+ const result = {};
111
+ for (const [key, child] of Object.entries(value)) {
112
+ if (child !== undefined)
113
+ result[key] = canonicalPayload(child, depth + 1, budget);
114
+ }
115
+ return result;
116
+ }
117
+ throw new ValidationError("operation payload contains null, undefined, or a non-canonical value");
118
+ }
119
+ /** Encode one schema-derived operation payload exactly like cigar-api. */
120
+ export function encodeOperationPayload(value) {
121
+ return deterministicCbor(canonicalPayload(value));
122
+ }
123
+ class PayloadCborParser {
124
+ #position = 0;
125
+ #nodes = 0;
126
+ #source;
127
+ constructor(source) {
128
+ this.#source = source;
129
+ }
130
+ get done() {
131
+ return this.#position === this.#source.length;
132
+ }
133
+ #exact(length) {
134
+ const end = this.#position + length;
135
+ if (!Number.isSafeInteger(length) || length < 0 || end > this.#source.length)
136
+ throw new ValidationError("payload CBOR is truncated");
137
+ const value = this.#source.slice(this.#position, end);
138
+ this.#position = end;
139
+ return value;
140
+ }
141
+ #byte() {
142
+ const value = this.#exact(1)[0];
143
+ if (value === undefined)
144
+ throw new ValidationError("payload CBOR is truncated");
145
+ return value;
146
+ }
147
+ #argument(additional) {
148
+ if (additional < 24)
149
+ return BigInt(additional);
150
+ const widths = new Map([[24, 1], [25, 2], [26, 4], [27, 8]]);
151
+ const width = widths.get(additional);
152
+ if (width === undefined)
153
+ throw new ValidationError("payload CBOR uses an indefinite or reserved form");
154
+ let value = 0n;
155
+ for (const byte of this.#exact(width))
156
+ value = (value << 8n) | BigInt(byte);
157
+ const minimum = new Map([[1, 24n], [2, 0x100n], [4, 0x10000n], [8, 0x100000000n]]).get(width);
158
+ if (minimum === undefined || value < minimum)
159
+ throw new ValidationError("payload CBOR integer is non-canonical");
160
+ return value;
161
+ }
162
+ parse(depth = 0) {
163
+ this.#nodes += 1;
164
+ if (depth > 64 || this.#nodes > 100_000)
165
+ throw new ValidationError("payload CBOR exceeds nesting or node bounds");
166
+ const initial = this.#byte();
167
+ const major = initial >> 5;
168
+ const additional = initial & 31;
169
+ if (major === 0 || major === 1) {
170
+ const argument = this.#argument(additional);
171
+ const value = major === 0 ? argument : -1n - argument;
172
+ if (value < -(1n << 63n))
173
+ throw new ValidationError("payload CBOR integer exceeds i64");
174
+ return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value;
175
+ }
176
+ if (major === 2 || major === 3) {
177
+ const length = Number(this.#argument(additional));
178
+ const bytes = this.#exact(length);
179
+ if (major === 2)
180
+ return bytes;
181
+ try {
182
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes).normalize("NFC");
183
+ }
184
+ catch (cause) {
185
+ throw new ValidationError("payload CBOR text is invalid UTF-8", { cause });
186
+ }
187
+ }
188
+ if (major === 4) {
189
+ const length = Number(this.#argument(additional));
190
+ if (!Number.isSafeInteger(length) || length > 100_000)
191
+ throw new ValidationError("payload CBOR collection exceeds its node bound");
192
+ return Array.from({ length }, () => this.parse(depth + 1));
193
+ }
194
+ if (major === 5) {
195
+ const length = Number(this.#argument(additional));
196
+ if (!Number.isSafeInteger(length) || length > 100_000)
197
+ throw new ValidationError("payload CBOR collection exceeds its node bound");
198
+ const result = {};
199
+ let previous;
200
+ for (let index = 0; index < length; index += 1) {
201
+ const start = this.#position;
202
+ const key = this.parse(depth + 1);
203
+ const encoded = this.#source.slice(start, this.#position);
204
+ if (typeof key !== "string" || (previous !== undefined && Buffer.compare(previous, encoded) >= 0) || key in result) {
205
+ throw new ValidationError("payload CBOR map keys are not canonical and unique");
206
+ }
207
+ previous = encoded;
208
+ result[key] = this.parse(depth + 1);
209
+ }
210
+ return result;
211
+ }
212
+ if (major === 7 && additional === 20)
213
+ return false;
214
+ if (major === 7 && additional === 21)
215
+ return true;
216
+ throw new ValidationError("payload CBOR contains a forbidden tag, null, float, or simple value");
217
+ }
218
+ }
219
+ /** Strictly decode one canonical typed operation payload. */
220
+ export function decodeOperationPayload(source) {
221
+ const parser = new PayloadCborParser(source);
222
+ const value = parser.parse();
223
+ if (!parser.done || Buffer.compare(deterministicCbor(value), source) !== 0) {
224
+ throw new ValidationError("payload CBOR is not deterministic");
225
+ }
226
+ return value;
227
+ }
228
+ function multihash(domain, canonical) {
229
+ const digest = createHash("sha256")
230
+ .update(domain)
231
+ .update(Uint8Array.of(0))
232
+ .update("v1")
233
+ .update(Uint8Array.of(0))
234
+ .update(canonical)
235
+ .digest("hex");
236
+ return `1220${digest}`;
237
+ }
238
+ /** Compute an ordinary raw SHA-256 multihash (used for sealed delta JSON). */
239
+ export function rawMultihash(bytes) {
240
+ return `1220${createHash("sha256").update(bytes).digest("hex")}`;
241
+ }
242
+ function assertDigest(value, field) {
243
+ if (!DIGEST.test(value))
244
+ throw new ValidationError(`${field} must be a lowercase SHA-256 multihash`);
245
+ }
246
+ function exactKeys(value, expected, context) {
247
+ const actual = Object.keys(value).sort();
248
+ const sorted = [...expected].sort();
249
+ if (actual.length !== sorted.length || actual.some((key, index) => key !== sorted[index])) {
250
+ throw new ValidationError(`${context} has unknown or missing fields`);
251
+ }
252
+ }
253
+ function validateBlock(block, index) {
254
+ const expected = ["block_id", "lane", "representation", "content_digest", "token_count", "provenance"];
255
+ const receiptPresent = Object.hasOwn(block, "transform_receipt");
256
+ if (receiptPresent)
257
+ expected.push("transform_receipt");
258
+ exactKeys(block, expected, `block ${index}`);
259
+ assertDigest(block.block_id, `block ${index} id`);
260
+ assertDigest(block.content_digest, `block ${index} content digest`);
261
+ if (!LANE_ORDER.has(block.lane))
262
+ throw new ValidationError(`block ${index} has an unknown lane`);
263
+ if (!["exact", "extracted", "summarized", "redacted"].includes(block.representation)) {
264
+ throw new ValidationError(`block ${index} has an unknown representation`);
265
+ }
266
+ if (!Number.isInteger(block.token_count) || block.token_count < 1 || block.token_count > 0xffff_ffff) {
267
+ throw new ValidationError(`block ${index} token count is invalid`);
268
+ }
269
+ if (block.provenance.length < 1 || block.provenance.length > 10_000) {
270
+ throw new ValidationError(`block ${index} provenance count is invalid`);
271
+ }
272
+ block.provenance.forEach((item) => assertDigest(item, `block ${index} provenance`));
273
+ if (!block.provenance.every((item, ordinal) => ordinal === 0 || (block.provenance[ordinal - 1] ?? "") < item)) {
274
+ throw new ValidationError(`block ${index} provenance must be sorted and unique`);
275
+ }
276
+ const receiptRequired = block.representation === "extracted" || block.representation === "summarized";
277
+ if (receiptRequired !== receiptPresent) {
278
+ throw new ValidationError(`block ${index} extracted and summarized representations require exactly one transform receipt`);
279
+ }
280
+ if (receiptPresent) {
281
+ assertDigest(block.transform_receipt, `block ${index} transform receipt`);
282
+ }
283
+ }
284
+ function canonicalBlock(block) {
285
+ return {
286
+ block_id: block.block_id,
287
+ lane: block.lane,
288
+ representation: block.representation,
289
+ content_digest: block.content_digest,
290
+ token_count: block.token_count,
291
+ provenance: block.provenance,
292
+ ...(block.transform_receipt === undefined ? {} : { transform_receipt: block.transform_receipt }),
293
+ };
294
+ }
295
+ function canonicalExtensions(value) {
296
+ return value;
297
+ }
298
+ /** Compute the semantic v1 bundle identity, excluding the self-derived bundle_id. */
299
+ export function bundleId(bundle) {
300
+ bundle.blocks.forEach((block, index) => validateBlock(block, index));
301
+ const fields = {
302
+ schema_version: bundle.schema_version,
303
+ contract_digest: bundle.contract_digest,
304
+ manifest_digest: bundle.manifest_digest,
305
+ blocks: bundle.blocks.map(canonicalBlock),
306
+ total_tokens: bundle.total_tokens,
307
+ extensions: canonicalExtensions(bundle.extensions),
308
+ };
309
+ return multihash("CIGAR-BUNDLE", deterministicCbor([2, fields]));
310
+ }
311
+ /** Validate structural invariants and prove the content-derived bundle identity. */
312
+ export function verifyBundle(bundle) {
313
+ exactKeys(bundle, ["schema_version", "bundle_id", "contract_digest", "manifest_digest", "blocks", "total_tokens", "extensions"], "bundle");
314
+ if (bundle.schema_version !== "cigar.context-bundle.v1")
315
+ throw new ValidationError("unsupported bundle schema");
316
+ assertDigest(bundle.bundle_id, "bundle id");
317
+ assertDigest(bundle.contract_digest, "contract digest");
318
+ assertDigest(bundle.manifest_digest, "manifest digest");
319
+ if (bundle.blocks.length > 10_000)
320
+ throw new ValidationError("bundle has too many blocks");
321
+ let total = 0;
322
+ let previous;
323
+ for (const [index, block] of bundle.blocks.entries()) {
324
+ validateBlock(block, index);
325
+ const order = LANE_ORDER.get(block.lane) ?? -1;
326
+ const previousOrder = previous === undefined ? -1 : (LANE_ORDER.get(previous.lane) ?? -1);
327
+ if (previous !== undefined && (order < previousOrder || (order === previousOrder && block.block_id <= previous.block_id))) {
328
+ throw new ValidationError("bundle blocks must be lane/id sorted and unique");
329
+ }
330
+ total += block.token_count;
331
+ if (total > 0xffff_ffff)
332
+ throw new ValidationError("bundle token sum exceeds u32");
333
+ previous = block;
334
+ }
335
+ if (!Number.isInteger(bundle.total_tokens) || bundle.total_tokens !== total) {
336
+ throw new ValidationError("bundle token total is not exact");
337
+ }
338
+ if (bundleId(bundle) !== bundle.bundle_id)
339
+ throw new ValidationError("bundle identity verification failed");
340
+ }
341
+ function deltaJson(delta) {
342
+ const blocks = delta.added_blocks.map((block) => ({
343
+ block_id: block.block_id,
344
+ lane: block.lane,
345
+ representation: block.representation,
346
+ content_digest: block.content_digest,
347
+ token_count: block.token_count,
348
+ provenance: [...block.provenance],
349
+ ...(block.transform_receipt === undefined ? {} : { transform_receipt: block.transform_receipt }),
350
+ }));
351
+ return new TextEncoder().encode(JSON.stringify({
352
+ schema_version: delta.schema_version,
353
+ base_bundle_id: delta.base_bundle_id,
354
+ target_bundle_id: delta.target_bundle_id,
355
+ added_blocks: blocks,
356
+ removed_block_ids: [...delta.removed_block_ids],
357
+ resulting_tokens: delta.resulting_tokens,
358
+ }));
359
+ }
360
+ export function deltaDigest(delta) {
361
+ delta.added_blocks.forEach((block, index) => validateBlock(block, index));
362
+ return rawMultihash(deltaJson(delta));
363
+ }
364
+ /** Apply and verify a sealed delta against an exact expected target bundle. */
365
+ export function applyContextDelta(base, expectedTarget, delta, sealedDigest) {
366
+ verifyBundle(base);
367
+ verifyBundle(expectedTarget);
368
+ exactKeys(delta, ["schema_version", "base_bundle_id", "target_bundle_id", "added_blocks", "removed_block_ids", "resulting_tokens"], "delta");
369
+ if (delta.schema_version !== "cigar.context-delta.v1")
370
+ throw new ValidationError("unsupported delta schema");
371
+ if (delta.base_bundle_id !== base.bundle_id)
372
+ throw new ValidationError("delta base does not match");
373
+ if (delta.target_bundle_id !== expectedTarget.bundle_id)
374
+ throw new ValidationError("delta target does not match");
375
+ if (deltaDigest(delta) !== sealedDigest)
376
+ throw new ValidationError("sealed delta digest does not match");
377
+ const blocks = new Map(base.blocks.map((block) => [block.block_id, block]));
378
+ let previousRemoved = "";
379
+ for (const id of delta.removed_block_ids) {
380
+ assertDigest(id, "removed block id");
381
+ if (id <= previousRemoved || !blocks.delete(id))
382
+ throw new ValidationError("delta removal set is invalid for the base");
383
+ previousRemoved = id;
384
+ }
385
+ let previousAdded = "";
386
+ for (const [index, block] of delta.added_blocks.entries()) {
387
+ validateBlock(block, index);
388
+ if (block.block_id <= previousAdded || blocks.has(block.block_id))
389
+ throw new ValidationError("delta addition set is invalid");
390
+ if (delta.removed_block_ids.includes(block.block_id))
391
+ throw new ValidationError("delta both adds and removes a block");
392
+ blocks.set(block.block_id, block);
393
+ previousAdded = block.block_id;
394
+ }
395
+ if (delta.resulting_tokens !== expectedTarget.total_tokens || blocks.size !== expectedTarget.blocks.length) {
396
+ throw new ValidationError("delta result does not match target accounting");
397
+ }
398
+ for (const target of expectedTarget.blocks) {
399
+ const actual = blocks.get(target.block_id);
400
+ if (actual === undefined || JSON.stringify(actual) !== JSON.stringify(target)) {
401
+ throw new ValidationError("delta result does not reproduce the target");
402
+ }
403
+ }
404
+ return structuredClone(expectedTarget);
405
+ }
406
+ //# sourceMappingURL=digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport { ValidationError } from \"./errors.js\";\nimport type { SemanticBundleBlock, SemanticContextBundle, SemanticContextDelta } from \"./types.js\";\n\ntype Canonical = boolean | bigint | number | string | Uint8Array | readonly Canonical[] | { readonly [key: string]: Canonical };\n\nconst DIGEST = /^1220[0-9a-f]{64}$/u;\nconst LANE_ORDER = new Map([\n [\"rules\", 0],\n [\"task\", 1],\n [\"evidence\", 2],\n [\"history\", 3],\n [\"tools\", 4],\n]);\n\nfunction concatenate(parts: readonly Uint8Array[]): Uint8Array {\n const result = new Uint8Array(parts.reduce((total, part) => total + part.length, 0));\n let offset = 0;\n for (const part of parts) {\n result.set(part, offset);\n offset += part.length;\n }\n return result;\n}\n\nfunction head(major: number, argument: bigint): Uint8Array {\n if (argument < 0n || argument > 0xffff_ffff_ffff_ffffn) throw new ValidationError(\"canonical integer exceeds u64\");\n const prefix = major << 5;\n if (argument < 24n) return Uint8Array.of(prefix | Number(argument));\n const widths: readonly [bigint, number, number][] = [\n [0xffn, 24, 1],\n [0xffffn, 25, 2],\n [0xffff_ffffn, 26, 4],\n [0xffff_ffff_ffff_ffffn, 27, 8],\n ];\n for (const [maximum, additional, width] of widths) {\n if (argument <= maximum) {\n const output = new Uint8Array(width + 1);\n output[0] = prefix | additional;\n let remainder = argument;\n for (let index = width; index > 0; index -= 1) {\n output[index] = Number(remainder & 0xffn);\n remainder >>= 8n;\n }\n return output;\n }\n }\n throw new ValidationError(\"canonical integer exceeds u64\");\n}\n\n/** Encode the frozen CIGAR deterministic-CBOR subset. */\nexport function deterministicCbor(value: Canonical): Uint8Array {\n return encodeCanonical(value, 0, { nodes: 0 });\n}\n\nfunction encodeCanonical(value: Canonical, depth: number, budget: { nodes: number }): Uint8Array {\n budget.nodes += 1;\n if (depth > 64 || budget.nodes > 100_000) throw new ValidationError(\"canonical value exceeds nesting or node bounds\");\n if (value === false) return Uint8Array.of(0xf4);\n if (value === true) return Uint8Array.of(0xf5);\n if (typeof value === \"number\") {\n if (!Number.isSafeInteger(value)) throw new ValidationError(\"canonical numbers must be safe integers; use bigint for wider values\");\n return encodeCanonical(BigInt(value), depth, budget);\n }\n if (typeof value === \"bigint\") {\n if (value < -(1n << 63n)) throw new ValidationError(\"canonical signed integer is below i64\");\n return value >= 0n ? head(0, value) : head(1, -1n - value);\n }\n if (typeof value === \"string\") {\n const encoded = new TextEncoder().encode(value.normalize(\"NFC\"));\n return concatenate([head(3, BigInt(encoded.length)), encoded]);\n }\n if (value instanceof Uint8Array) return concatenate([head(2, BigInt(value.length)), value]);\n if (Array.isArray(value)) {\n return concatenate([head(4, BigInt(value.length)), ...value.map((child) => encodeCanonical(child, depth + 1, budget))]);\n }\n if (typeof value !== \"object\" || value === null) throw new ValidationError(\"null is not canonical\");\n const entries = Object.entries(value).map(([key, child]) => {\n if (child === undefined || child === null) throw new ValidationError(\"undefined and null are not canonical\");\n return { key: encodeCanonical(key, depth + 1, budget), child };\n });\n entries.sort((left, right) => Buffer.compare(left.key, right.key));\n for (let index = 1; index < entries.length; index += 1) {\n if (Buffer.compare(entries[index - 1]?.key ?? new Uint8Array(), entries[index]?.key ?? new Uint8Array()) === 0) {\n throw new ValidationError(\"canonical map contains a duplicate key\");\n }\n }\n return concatenate([\n head(5, BigInt(entries.length)),\n ...entries.flatMap(({ key, child }) => [key, encodeCanonical(child, depth + 1, budget)]),\n ]);\n}\n\nfunction canonicalPayload(value: unknown, depth = 0, budget = { nodes: 0 }): Canonical {\n budget.nodes += 1;\n if (depth > 64 || budget.nodes > 100_000) throw new ValidationError(\"operation payload exceeds nesting or node bounds\");\n if (typeof value === \"boolean\" || typeof value === \"string\" || typeof value === \"bigint\" || value instanceof Uint8Array) {\n return value;\n }\n if (typeof value === \"number\") {\n if (!Number.isSafeInteger(value)) throw new ValidationError(\"payload numbers must be safe integers; use bigint for int64/uint64\");\n return value;\n }\n if (Array.isArray(value)) return value.map((child) => canonicalPayload(child, depth + 1, budget));\n if (typeof value === \"object\" && value !== null) {\n const result: Record<string, Canonical> = {};\n for (const [key, child] of Object.entries(value)) {\n if (child !== undefined) result[key] = canonicalPayload(child, depth + 1, budget);\n }\n return result;\n }\n throw new ValidationError(\"operation payload contains null, undefined, or a non-canonical value\");\n}\n\n/** Encode one schema-derived operation payload exactly like cigar-api. */\nexport function encodeOperationPayload(value: unknown): Uint8Array {\n return deterministicCbor(canonicalPayload(value));\n}\n\nclass PayloadCborParser {\n #position = 0;\n #nodes = 0;\n readonly #source: Uint8Array;\n\n constructor(source: Uint8Array) {\n this.#source = source;\n }\n\n get done(): boolean {\n return this.#position === this.#source.length;\n }\n\n #exact(length: number): Uint8Array {\n const end = this.#position + length;\n if (!Number.isSafeInteger(length) || length < 0 || end > this.#source.length) throw new ValidationError(\"payload CBOR is truncated\");\n const value = this.#source.slice(this.#position, end);\n this.#position = end;\n return value;\n }\n\n #byte(): number {\n const value = this.#exact(1)[0];\n if (value === undefined) throw new ValidationError(\"payload CBOR is truncated\");\n return value;\n }\n\n #argument(additional: number): bigint {\n if (additional < 24) return BigInt(additional);\n const widths = new Map([[24, 1], [25, 2], [26, 4], [27, 8]]);\n const width = widths.get(additional);\n if (width === undefined) throw new ValidationError(\"payload CBOR uses an indefinite or reserved form\");\n let value = 0n;\n for (const byte of this.#exact(width)) value = (value << 8n) | BigInt(byte);\n const minimum = new Map([[1, 24n], [2, 0x100n], [4, 0x1_0000n], [8, 0x1_0000_0000n]]).get(width);\n if (minimum === undefined || value < minimum) throw new ValidationError(\"payload CBOR integer is non-canonical\");\n return value;\n }\n\n parse(depth = 0): Canonical {\n this.#nodes += 1;\n if (depth > 64 || this.#nodes > 100_000) throw new ValidationError(\"payload CBOR exceeds nesting or node bounds\");\n const initial = this.#byte();\n const major = initial >> 5;\n const additional = initial & 31;\n if (major === 0 || major === 1) {\n const argument = this.#argument(additional);\n const value = major === 0 ? argument : -1n - argument;\n if (value < -(1n << 63n)) throw new ValidationError(\"payload CBOR integer exceeds i64\");\n return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value;\n }\n if (major === 2 || major === 3) {\n const length = Number(this.#argument(additional));\n const bytes = this.#exact(length);\n if (major === 2) return bytes;\n try {\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes).normalize(\"NFC\");\n } catch (cause) {\n throw new ValidationError(\"payload CBOR text is invalid UTF-8\", { cause });\n }\n }\n if (major === 4) {\n const length = Number(this.#argument(additional));\n if (!Number.isSafeInteger(length) || length > 100_000) throw new ValidationError(\"payload CBOR collection exceeds its node bound\");\n return Array.from({ length }, () => this.parse(depth + 1));\n }\n if (major === 5) {\n const length = Number(this.#argument(additional));\n if (!Number.isSafeInteger(length) || length > 100_000) throw new ValidationError(\"payload CBOR collection exceeds its node bound\");\n const result: Record<string, Canonical> = {};\n let previous: Uint8Array | undefined;\n for (let index = 0; index < length; index += 1) {\n const start = this.#position;\n const key = this.parse(depth + 1);\n const encoded = this.#source.slice(start, this.#position);\n if (typeof key !== \"string\" || (previous !== undefined && Buffer.compare(previous, encoded) >= 0) || key in result) {\n throw new ValidationError(\"payload CBOR map keys are not canonical and unique\");\n }\n previous = encoded;\n result[key] = this.parse(depth + 1);\n }\n return result;\n }\n if (major === 7 && additional === 20) return false;\n if (major === 7 && additional === 21) return true;\n throw new ValidationError(\"payload CBOR contains a forbidden tag, null, float, or simple value\");\n }\n}\n\n/** Strictly decode one canonical typed operation payload. */\nexport function decodeOperationPayload(source: Uint8Array): unknown {\n const parser = new PayloadCborParser(source);\n const value = parser.parse();\n if (!parser.done || Buffer.compare(deterministicCbor(value), source) !== 0) {\n throw new ValidationError(\"payload CBOR is not deterministic\");\n }\n return value;\n}\n\nfunction multihash(domain: string, canonical: Uint8Array): string {\n const digest = createHash(\"sha256\")\n .update(domain)\n .update(Uint8Array.of(0))\n .update(\"v1\")\n .update(Uint8Array.of(0))\n .update(canonical)\n .digest(\"hex\");\n return `1220${digest}`;\n}\n\n/** Compute an ordinary raw SHA-256 multihash (used for sealed delta JSON). */\nexport function rawMultihash(bytes: Uint8Array): string {\n return `1220${createHash(\"sha256\").update(bytes).digest(\"hex\")}`;\n}\n\nfunction assertDigest(value: string, field: string): void {\n if (!DIGEST.test(value)) throw new ValidationError(`${field} must be a lowercase SHA-256 multihash`);\n}\n\nfunction exactKeys(value: object, expected: readonly string[], context: string): void {\n const actual = Object.keys(value).sort();\n const sorted = [...expected].sort();\n if (actual.length !== sorted.length || actual.some((key, index) => key !== sorted[index])) {\n throw new ValidationError(`${context} has unknown or missing fields`);\n }\n}\n\nfunction validateBlock(block: SemanticBundleBlock, index: number): void {\n const expected = [\"block_id\", \"lane\", \"representation\", \"content_digest\", \"token_count\", \"provenance\"];\n const receiptPresent = Object.hasOwn(block, \"transform_receipt\");\n if (receiptPresent) expected.push(\"transform_receipt\");\n exactKeys(block, expected, `block ${index}`);\n assertDigest(block.block_id, `block ${index} id`);\n assertDigest(block.content_digest, `block ${index} content digest`);\n if (!LANE_ORDER.has(block.lane)) throw new ValidationError(`block ${index} has an unknown lane`);\n if (![\"exact\", \"extracted\", \"summarized\", \"redacted\"].includes(block.representation)) {\n throw new ValidationError(`block ${index} has an unknown representation`);\n }\n if (!Number.isInteger(block.token_count) || block.token_count < 1 || block.token_count > 0xffff_ffff) {\n throw new ValidationError(`block ${index} token count is invalid`);\n }\n if (block.provenance.length < 1 || block.provenance.length > 10_000) {\n throw new ValidationError(`block ${index} provenance count is invalid`);\n }\n block.provenance.forEach((item) => assertDigest(item, `block ${index} provenance`));\n if (!block.provenance.every((item, ordinal) => ordinal === 0 || (block.provenance[ordinal - 1] ?? \"\") < item)) {\n throw new ValidationError(`block ${index} provenance must be sorted and unique`);\n }\n const receiptRequired = block.representation === \"extracted\" || block.representation === \"summarized\";\n if (receiptRequired !== receiptPresent) {\n throw new ValidationError(`block ${index} extracted and summarized representations require exactly one transform receipt`);\n }\n if (receiptPresent) {\n assertDigest(block.transform_receipt as string, `block ${index} transform receipt`);\n }\n}\n\nfunction canonicalBlock(block: SemanticBundleBlock): Record<string, Canonical> {\n return {\n block_id: block.block_id,\n lane: block.lane,\n representation: block.representation,\n content_digest: block.content_digest,\n token_count: block.token_count,\n provenance: block.provenance,\n ...(block.transform_receipt === undefined ? {} : { transform_receipt: block.transform_receipt }),\n };\n}\n\nfunction canonicalExtensions(value: Readonly<Record<string, unknown>>): Record<string, Canonical> {\n return value as Record<string, Canonical>;\n}\n\n/** Compute the semantic v1 bundle identity, excluding the self-derived bundle_id. */\nexport function bundleId(bundle: SemanticContextBundle): string {\n bundle.blocks.forEach((block, index) => validateBlock(block, index));\n const fields: Record<string, Canonical> = {\n schema_version: bundle.schema_version,\n contract_digest: bundle.contract_digest,\n manifest_digest: bundle.manifest_digest,\n blocks: bundle.blocks.map(canonicalBlock),\n total_tokens: bundle.total_tokens,\n extensions: canonicalExtensions(bundle.extensions),\n };\n return multihash(\"CIGAR-BUNDLE\", deterministicCbor([2, fields]));\n}\n\n/** Validate structural invariants and prove the content-derived bundle identity. */\nexport function verifyBundle(bundle: SemanticContextBundle): void {\n exactKeys(\n bundle,\n [\"schema_version\", \"bundle_id\", \"contract_digest\", \"manifest_digest\", \"blocks\", \"total_tokens\", \"extensions\"],\n \"bundle\",\n );\n if (bundle.schema_version !== \"cigar.context-bundle.v1\") throw new ValidationError(\"unsupported bundle schema\");\n assertDigest(bundle.bundle_id, \"bundle id\");\n assertDigest(bundle.contract_digest, \"contract digest\");\n assertDigest(bundle.manifest_digest, \"manifest digest\");\n if (bundle.blocks.length > 10_000) throw new ValidationError(\"bundle has too many blocks\");\n let total = 0;\n let previous: SemanticBundleBlock | undefined;\n for (const [index, block] of bundle.blocks.entries()) {\n validateBlock(block, index);\n const order = LANE_ORDER.get(block.lane) ?? -1;\n const previousOrder = previous === undefined ? -1 : (LANE_ORDER.get(previous.lane) ?? -1);\n if (previous !== undefined && (order < previousOrder || (order === previousOrder && block.block_id <= previous.block_id))) {\n throw new ValidationError(\"bundle blocks must be lane/id sorted and unique\");\n }\n total += block.token_count;\n if (total > 0xffff_ffff) throw new ValidationError(\"bundle token sum exceeds u32\");\n previous = block;\n }\n if (!Number.isInteger(bundle.total_tokens) || bundle.total_tokens !== total) {\n throw new ValidationError(\"bundle token total is not exact\");\n }\n if (bundleId(bundle) !== bundle.bundle_id) throw new ValidationError(\"bundle identity verification failed\");\n}\n\nfunction deltaJson(delta: SemanticContextDelta): Uint8Array {\n const blocks = delta.added_blocks.map((block) => ({\n block_id: block.block_id,\n lane: block.lane,\n representation: block.representation,\n content_digest: block.content_digest,\n token_count: block.token_count,\n provenance: [...block.provenance],\n ...(block.transform_receipt === undefined ? {} : { transform_receipt: block.transform_receipt }),\n }));\n return new TextEncoder().encode(JSON.stringify({\n schema_version: delta.schema_version,\n base_bundle_id: delta.base_bundle_id,\n target_bundle_id: delta.target_bundle_id,\n added_blocks: blocks,\n removed_block_ids: [...delta.removed_block_ids],\n resulting_tokens: delta.resulting_tokens,\n }));\n}\n\nexport function deltaDigest(delta: SemanticContextDelta): string {\n delta.added_blocks.forEach((block, index) => validateBlock(block, index));\n return rawMultihash(deltaJson(delta));\n}\n\n/** Apply and verify a sealed delta against an exact expected target bundle. */\nexport function applyContextDelta(\n base: SemanticContextBundle,\n expectedTarget: SemanticContextBundle,\n delta: SemanticContextDelta,\n sealedDigest: string,\n): SemanticContextBundle {\n verifyBundle(base);\n verifyBundle(expectedTarget);\n exactKeys(delta, [\"schema_version\", \"base_bundle_id\", \"target_bundle_id\", \"added_blocks\", \"removed_block_ids\", \"resulting_tokens\"], \"delta\");\n if (delta.schema_version !== \"cigar.context-delta.v1\") throw new ValidationError(\"unsupported delta schema\");\n if (delta.base_bundle_id !== base.bundle_id) throw new ValidationError(\"delta base does not match\");\n if (delta.target_bundle_id !== expectedTarget.bundle_id) throw new ValidationError(\"delta target does not match\");\n if (deltaDigest(delta) !== sealedDigest) throw new ValidationError(\"sealed delta digest does not match\");\n const blocks = new Map(base.blocks.map((block) => [block.block_id, block]));\n let previousRemoved = \"\";\n for (const id of delta.removed_block_ids) {\n assertDigest(id, \"removed block id\");\n if (id <= previousRemoved || !blocks.delete(id)) throw new ValidationError(\"delta removal set is invalid for the base\");\n previousRemoved = id;\n }\n let previousAdded = \"\";\n for (const [index, block] of delta.added_blocks.entries()) {\n validateBlock(block, index);\n if (block.block_id <= previousAdded || blocks.has(block.block_id)) throw new ValidationError(\"delta addition set is invalid\");\n if (delta.removed_block_ids.includes(block.block_id)) throw new ValidationError(\"delta both adds and removes a block\");\n blocks.set(block.block_id, block);\n previousAdded = block.block_id;\n }\n if (delta.resulting_tokens !== expectedTarget.total_tokens || blocks.size !== expectedTarget.blocks.length) {\n throw new ValidationError(\"delta result does not match target accounting\");\n }\n for (const target of expectedTarget.blocks) {\n const actual = blocks.get(target.block_id);\n if (actual === undefined || JSON.stringify(actual) !== JSON.stringify(target)) {\n throw new ValidationError(\"delta result does not reproduce the target\");\n }\n }\n return structuredClone(expectedTarget);\n}\n"]}
@@ -0,0 +1,35 @@
1
+ export type RetryClass = "never" | "safe" | "after_backoff" | "after_reauthorization" | "after_reconciliation";
2
+ import { type ErrorCode } from "./generated/errors.js";
3
+ export interface ProblemDetails {
4
+ readonly schema_version: "cigar.problem.v1";
5
+ readonly code: ErrorCode;
6
+ readonly http_status: number;
7
+ readonly retry: RetryClass;
8
+ readonly message: string;
9
+ readonly remediation: string;
10
+ readonly correlation_id: string;
11
+ readonly details: Readonly<Record<string, unknown>>;
12
+ }
13
+ export declare class CigarError extends Error {
14
+ constructor(message: string, options?: ErrorOptions);
15
+ }
16
+ export declare class ValidationError extends CigarError {
17
+ }
18
+ export declare class CompatibilityError extends CigarError {
19
+ }
20
+ export declare class CigarTimeoutError extends CigarError {
21
+ }
22
+ export declare class TransportError extends CigarError {
23
+ }
24
+ export declare class CigarApiError extends CigarError {
25
+ readonly status: number;
26
+ readonly code: ErrorCode;
27
+ readonly numericCode: number;
28
+ readonly retry: RetryClass;
29
+ readonly correlationId: string;
30
+ readonly remediation: string;
31
+ readonly details: Readonly<Record<string, unknown>>;
32
+ constructor(status: number, problem: ProblemDetails);
33
+ }
34
+ export declare function isRetryable(error: unknown): boolean;
35
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,MAAM,GACN,eAAe,GACf,uBAAuB,GACvB,sBAAsB,CAAC;AAE3B,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEtE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,cAAc,EAAE,kBAAkB,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACrD;AAED,qBAAa,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAGlD;CACF;AAED,qBAAa,eAAgB,SAAQ,UAAU;CAAG;AAClD,qBAAa,kBAAmB,SAAQ,UAAU;CAAG;AACrD,qBAAa,iBAAkB,SAAQ,UAAU;CAAG;AACpD,qBAAa,cAAe,SAAQ,UAAU;CAAG;AAejD,qBAAa,aAAc,SAAQ,UAAU;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAEpD,YAAY,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EASlD;CACF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKnD","sourcesContent":["export type RetryClass =\n | \"never\"\n | \"safe\"\n | \"after_backoff\"\n | \"after_reauthorization\"\n | \"after_reconciliation\";\n\nimport { ERROR_CATALOG, type ErrorCode } from \"./generated/errors.js\";\n\nexport interface ProblemDetails {\n readonly schema_version: \"cigar.problem.v1\";\n readonly code: ErrorCode;\n readonly http_status: number;\n readonly retry: RetryClass;\n readonly message: string;\n readonly remediation: string;\n readonly correlation_id: string;\n readonly details: Readonly<Record<string, unknown>>;\n}\n\nexport class CigarError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\nexport class ValidationError extends CigarError {}\nexport class CompatibilityError extends CigarError {}\nexport class CigarTimeoutError extends CigarError {}\nexport class TransportError extends CigarError {}\n\nfunction immutableJson(value: unknown, depth = 0, budget = { nodes: 0 }): unknown {\n budget.nodes += 1;\n if (depth > 64 || budget.nodes > 100_000) throw new TransportError(\"problem details exceed nesting or node bounds\");\n if (Array.isArray(value)) return Object.freeze(value.map((child) => immutableJson(child, depth + 1, budget)));\n if (typeof value === \"object\" && value !== null) {\n return Object.freeze(Object.fromEntries(\n Object.entries(value).map(([key, child]) => [key, immutableJson(child, depth + 1, budget)]),\n ));\n }\n if (value === null || [\"boolean\", \"number\", \"string\"].includes(typeof value)) return value;\n throw new TransportError(\"problem details contain a non-JSON value\");\n}\n\nexport class CigarApiError extends CigarError {\n readonly status: number;\n readonly code: ErrorCode;\n readonly numericCode: number;\n readonly retry: RetryClass;\n readonly correlationId: string;\n readonly remediation: string;\n readonly details: Readonly<Record<string, unknown>>;\n\n constructor(status: number, problem: ProblemDetails) {\n super(`${problem.message} (CIGAR ${problem.code})`);\n this.status = status;\n this.code = problem.code;\n this.numericCode = ERROR_CATALOG[problem.code].numericCode;\n this.retry = problem.retry;\n this.correlationId = problem.correlation_id;\n this.remediation = problem.remediation;\n this.details = immutableJson(structuredClone(problem.details)) as Readonly<Record<string, unknown>>;\n }\n}\n\nexport function isRetryable(error: unknown): boolean {\n if (error instanceof CigarApiError) {\n return error.retry === \"safe\" || error.retry === \"after_backoff\";\n }\n return error instanceof TransportError || error instanceof CigarTimeoutError;\n}\n"]}
package/dist/errors.js ADDED
@@ -0,0 +1,54 @@
1
+ import { ERROR_CATALOG } from "./generated/errors.js";
2
+ export class CigarError extends Error {
3
+ constructor(message, options) {
4
+ super(message, options);
5
+ this.name = new.target.name;
6
+ }
7
+ }
8
+ export class ValidationError extends CigarError {
9
+ }
10
+ export class CompatibilityError extends CigarError {
11
+ }
12
+ export class CigarTimeoutError extends CigarError {
13
+ }
14
+ export class TransportError extends CigarError {
15
+ }
16
+ function immutableJson(value, depth = 0, budget = { nodes: 0 }) {
17
+ budget.nodes += 1;
18
+ if (depth > 64 || budget.nodes > 100_000)
19
+ throw new TransportError("problem details exceed nesting or node bounds");
20
+ if (Array.isArray(value))
21
+ return Object.freeze(value.map((child) => immutableJson(child, depth + 1, budget)));
22
+ if (typeof value === "object" && value !== null) {
23
+ return Object.freeze(Object.fromEntries(Object.entries(value).map(([key, child]) => [key, immutableJson(child, depth + 1, budget)])));
24
+ }
25
+ if (value === null || ["boolean", "number", "string"].includes(typeof value))
26
+ return value;
27
+ throw new TransportError("problem details contain a non-JSON value");
28
+ }
29
+ export class CigarApiError extends CigarError {
30
+ status;
31
+ code;
32
+ numericCode;
33
+ retry;
34
+ correlationId;
35
+ remediation;
36
+ details;
37
+ constructor(status, problem) {
38
+ super(`${problem.message} (CIGAR ${problem.code})`);
39
+ this.status = status;
40
+ this.code = problem.code;
41
+ this.numericCode = ERROR_CATALOG[problem.code].numericCode;
42
+ this.retry = problem.retry;
43
+ this.correlationId = problem.correlation_id;
44
+ this.remediation = problem.remediation;
45
+ this.details = immutableJson(structuredClone(problem.details));
46
+ }
47
+ }
48
+ export function isRetryable(error) {
49
+ if (error instanceof CigarApiError) {
50
+ return error.retry === "safe" || error.retry === "after_backoff";
51
+ }
52
+ return error instanceof TransportError || error instanceof CigarTimeoutError;
53
+ }
54
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["export type RetryClass =\n | \"never\"\n | \"safe\"\n | \"after_backoff\"\n | \"after_reauthorization\"\n | \"after_reconciliation\";\n\nimport { ERROR_CATALOG, type ErrorCode } from \"./generated/errors.js\";\n\nexport interface ProblemDetails {\n readonly schema_version: \"cigar.problem.v1\";\n readonly code: ErrorCode;\n readonly http_status: number;\n readonly retry: RetryClass;\n readonly message: string;\n readonly remediation: string;\n readonly correlation_id: string;\n readonly details: Readonly<Record<string, unknown>>;\n}\n\nexport class CigarError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\nexport class ValidationError extends CigarError {}\nexport class CompatibilityError extends CigarError {}\nexport class CigarTimeoutError extends CigarError {}\nexport class TransportError extends CigarError {}\n\nfunction immutableJson(value: unknown, depth = 0, budget = { nodes: 0 }): unknown {\n budget.nodes += 1;\n if (depth > 64 || budget.nodes > 100_000) throw new TransportError(\"problem details exceed nesting or node bounds\");\n if (Array.isArray(value)) return Object.freeze(value.map((child) => immutableJson(child, depth + 1, budget)));\n if (typeof value === \"object\" && value !== null) {\n return Object.freeze(Object.fromEntries(\n Object.entries(value).map(([key, child]) => [key, immutableJson(child, depth + 1, budget)]),\n ));\n }\n if (value === null || [\"boolean\", \"number\", \"string\"].includes(typeof value)) return value;\n throw new TransportError(\"problem details contain a non-JSON value\");\n}\n\nexport class CigarApiError extends CigarError {\n readonly status: number;\n readonly code: ErrorCode;\n readonly numericCode: number;\n readonly retry: RetryClass;\n readonly correlationId: string;\n readonly remediation: string;\n readonly details: Readonly<Record<string, unknown>>;\n\n constructor(status: number, problem: ProblemDetails) {\n super(`${problem.message} (CIGAR ${problem.code})`);\n this.status = status;\n this.code = problem.code;\n this.numericCode = ERROR_CATALOG[problem.code].numericCode;\n this.retry = problem.retry;\n this.correlationId = problem.correlation_id;\n this.remediation = problem.remediation;\n this.details = immutableJson(structuredClone(problem.details)) as Readonly<Record<string, unknown>>;\n }\n}\n\nexport function isRetryable(error: unknown): boolean {\n if (error instanceof CigarApiError) {\n return error.retry === \"safe\" || error.retry === \"after_backoff\";\n }\n return error instanceof TransportError || error instanceof CigarTimeoutError;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=quickstart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quickstart.d.ts","sourceRoot":"","sources":["../../src/examples/quickstart.ts"],"names":[],"mappings":"","sourcesContent":["import { readFile } from \"node:fs/promises\";\n\nimport {\n CigarClient,\n bundleId,\n createIdempotencyKey,\n verifyBundle,\n type SemanticContextBundle,\n} from \"../index.js\";\n\ninterface Fixture {\n readonly schema_version: string;\n readonly bundle: SemanticContextBundle;\n readonly expected_bundle_id: string;\n}\n\nconst fixtureUrl = new URL(\"../../fixtures/semantic-bundle-v1.json\", import.meta.url);\nconst fixture = JSON.parse(await readFile(fixtureUrl, \"utf8\")) as Fixture;\nif (fixture.schema_version !== \"cigar.sdk-semantic-bundle-fixture.v1\") throw new Error(\"unsupported fixture\");\nverifyBundle(fixture.bundle);\nconst identity = bundleId(fixture.bundle);\nif (identity !== fixture.expected_bundle_id) throw new Error(\"shared semantic bundle identity differs\");\n\nconst baseUrl = process.env.CIGAR_URL;\nif (baseUrl !== undefined) {\n const planId = process.env.CIGAR_PLAN_ID;\n if (planId === undefined) throw new Error(\"CIGAR_PLAN_ID is required with CIGAR_URL\");\n const client = new CigarClient({\n baseUrl,\n allowInsecureLoopback: baseUrl.startsWith(\"http://\"),\n ...(process.env.CIGAR_TOKEN === undefined ? {} : { bearerToken: process.env.CIGAR_TOKEN }),\n });\n await client.negotiate({ timeoutMs: 5_000 });\n const compiled = await client.compileContextBundle({\n payload: { plan_id: planId },\n idempotencyKey: createIdempotencyKey(\"quickstart\"),\n });\n if (compiled.payload.bundle_id !== identity) throw new Error(\"daemon bundle identity differs from the shared fixture\");\n const manifest = await client.getContextBundleManifest({ payload: { bundle_id: compiled.payload.bundle_id } });\n console.error(`verified daemon manifest ${manifest.payload.manifest_id}`);\n}\n\nconsole.log(identity);\n"]}
@@ -0,0 +1,32 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { CigarClient, bundleId, createIdempotencyKey, verifyBundle, } from "../index.js";
3
+ const fixtureUrl = new URL("../../fixtures/semantic-bundle-v1.json", import.meta.url);
4
+ const fixture = JSON.parse(await readFile(fixtureUrl, "utf8"));
5
+ if (fixture.schema_version !== "cigar.sdk-semantic-bundle-fixture.v1")
6
+ throw new Error("unsupported fixture");
7
+ verifyBundle(fixture.bundle);
8
+ const identity = bundleId(fixture.bundle);
9
+ if (identity !== fixture.expected_bundle_id)
10
+ throw new Error("shared semantic bundle identity differs");
11
+ const baseUrl = process.env.CIGAR_URL;
12
+ if (baseUrl !== undefined) {
13
+ const planId = process.env.CIGAR_PLAN_ID;
14
+ if (planId === undefined)
15
+ throw new Error("CIGAR_PLAN_ID is required with CIGAR_URL");
16
+ const client = new CigarClient({
17
+ baseUrl,
18
+ allowInsecureLoopback: baseUrl.startsWith("http://"),
19
+ ...(process.env.CIGAR_TOKEN === undefined ? {} : { bearerToken: process.env.CIGAR_TOKEN }),
20
+ });
21
+ await client.negotiate({ timeoutMs: 5_000 });
22
+ const compiled = await client.compileContextBundle({
23
+ payload: { plan_id: planId },
24
+ idempotencyKey: createIdempotencyKey("quickstart"),
25
+ });
26
+ if (compiled.payload.bundle_id !== identity)
27
+ throw new Error("daemon bundle identity differs from the shared fixture");
28
+ const manifest = await client.getContextBundleManifest({ payload: { bundle_id: compiled.payload.bundle_id } });
29
+ console.error(`verified daemon manifest ${manifest.payload.manifest_id}`);
30
+ }
31
+ console.log(identity);
32
+ //# sourceMappingURL=quickstart.js.map