@zanii/blackbox 0.21.2 → 0.23.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 (95) hide show
  1. package/README.md +1 -0
  2. package/dist/actions/index.d.ts +29 -0
  3. package/dist/actions/index.js +114 -0
  4. package/dist/admission/index.d.ts +30 -0
  5. package/dist/admission/index.js +106 -0
  6. package/dist/analysis/accepted.d.ts +26 -0
  7. package/dist/analysis/accepted.js +61 -0
  8. package/dist/analysis/detectors.js +12 -9
  9. package/dist/analysis/faults.js +71 -0
  10. package/dist/analysis/grounding.js +5 -9
  11. package/dist/analysis/guard.d.ts +72 -0
  12. package/dist/analysis/guard.js +240 -0
  13. package/dist/analysis/hallucination.js +2 -2
  14. package/dist/analysis/index.d.ts +21 -1
  15. package/dist/analysis/index.js +101 -19
  16. package/dist/analysis/injection.d.ts +2 -1
  17. package/dist/analysis/injection.js +16 -16
  18. package/dist/analysis/landing.js +60 -14
  19. package/dist/analysis/plan-checks.d.ts +55 -0
  20. package/dist/analysis/plan-checks.js +748 -0
  21. package/dist/analysis/taxonomy.js +1 -0
  22. package/dist/analysis/waste.js +2 -3
  23. package/dist/approvals/index.d.ts +12 -3
  24. package/dist/approvals/index.js +36 -10
  25. package/dist/authority/index.js +3 -3
  26. package/dist/aviation/index.d.ts +422 -0
  27. package/dist/aviation/index.js +1014 -0
  28. package/dist/aviation/qrh.d.ts +4 -0
  29. package/dist/aviation/qrh.js +171 -0
  30. package/dist/budgets/index.d.ts +63 -0
  31. package/dist/budgets/index.js +161 -0
  32. package/dist/cli.js +199 -24
  33. package/dist/compliance/index.d.ts +2 -0
  34. package/dist/compliance/index.js +26 -2
  35. package/dist/cost/batch.d.ts +26 -0
  36. package/dist/cost/batch.js +173 -0
  37. package/dist/cost/index.d.ts +21 -0
  38. package/dist/cost/index.js +115 -30
  39. package/dist/cv/index.js +1 -1
  40. package/dist/duty/index.js +2 -1
  41. package/dist/evals/index.d.ts +233 -0
  42. package/dist/evals/index.js +488 -0
  43. package/dist/evidence/index.d.ts +9 -0
  44. package/dist/evidence/index.js +50 -0
  45. package/dist/federation/index.d.ts +9 -0
  46. package/dist/federation/index.js +8 -1
  47. package/dist/finance/index.js +3 -4
  48. package/dist/fleet/index.d.ts +25 -0
  49. package/dist/fleet/index.js +57 -17
  50. package/dist/fleet/insights.js +4 -1
  51. package/dist/health/index.js +2 -2
  52. package/dist/hooks/ai-sdk.d.ts +17 -19
  53. package/dist/hooks/ai-sdk.js +13 -7
  54. package/dist/hooks/index.d.ts +1 -0
  55. package/dist/hooks/index.js +1 -0
  56. package/dist/hooks/mastra.d.ts +26 -0
  57. package/dist/hooks/mastra.js +63 -0
  58. package/dist/index.d.ts +24 -9
  59. package/dist/index.js +25 -9
  60. package/dist/mcp-requests/index.d.ts +26 -0
  61. package/dist/mcp-requests/index.js +154 -0
  62. package/dist/mcp-server/index.d.ts +12 -0
  63. package/dist/mcp-server/index.js +84 -2
  64. package/dist/mcp-wrap/index.js +8 -4
  65. package/dist/otlp/index.d.ts +155 -0
  66. package/dist/otlp/index.js +468 -0
  67. package/dist/otlp/protobuf.d.ts +7 -0
  68. package/dist/otlp/protobuf.js +314 -0
  69. package/dist/packs/index.d.ts +2 -0
  70. package/dist/packs/index.js +5 -1
  71. package/dist/pdf/arabic.d.ts +45 -0
  72. package/dist/pdf/arabic.js +373 -0
  73. package/dist/pdf/index.d.ts +77 -0
  74. package/dist/pdf/index.js +673 -0
  75. package/dist/policy/index.d.ts +0 -4
  76. package/dist/policy/index.js +13 -5
  77. package/dist/realtime/index.d.ts +33 -0
  78. package/dist/realtime/index.js +204 -0
  79. package/dist/reconcile/record.d.ts +14 -0
  80. package/dist/reconcile/record.js +161 -66
  81. package/dist/session/index.d.ts +43 -0
  82. package/dist/session/index.js +83 -0
  83. package/dist/undo/index.js +3 -3
  84. package/dist/verify/anchor.d.ts +5 -1
  85. package/dist/verify/anchor.js +13 -4
  86. package/dist/verify/chain.d.ts +4 -0
  87. package/dist/verify/chain.js +4 -3
  88. package/dist/verify/envelope.d.ts +1 -1
  89. package/dist/verify/envelope.js +5 -0
  90. package/dist/version.d.ts +1 -1
  91. package/dist/version.js +1 -1
  92. package/dist/walls/index.js +2 -2
  93. package/dist/warehouse/index.d.ts +62 -0
  94. package/dist/warehouse/index.js +142 -0
  95. package/package.json +6 -3
@@ -0,0 +1,373 @@
1
+ // Arabic text for the signed PDF (spec/pdf.md §6): contextual shaping to the Unicode Arabic
2
+ // Presentation Forms (ArabicShaping.txt joining types, the lam-alef ligatures) and the Unicode
3
+ // bidirectional algorithm (UAX #9) for one paragraph without explicit embeddings. Pure, driven by
4
+ // the tables in spec/pdf/unicode-arabic.json, and identical to sdks/python/src/zanii_blackbox/
5
+ // pdf_arabic.py (spec/vectors/arabic-text.json).
6
+ function lookup(starts, values, fallback, cp) {
7
+ let lo = 0;
8
+ let hi = starts.length - 1;
9
+ let at = -1;
10
+ while (lo <= hi) {
11
+ const mid = (lo + hi) >> 1;
12
+ if (starts[mid] <= cp) {
13
+ at = mid;
14
+ lo = mid + 1;
15
+ }
16
+ else
17
+ hi = mid - 1;
18
+ }
19
+ return at < 0 ? fallback : values[at];
20
+ }
21
+ export function prepare(u) {
22
+ const bs = u.bidi.map((r) => r[0]);
23
+ const bv = u.bidi.map((r) => r[1]);
24
+ const js = u.joining.map((r) => r[0]);
25
+ return {
26
+ cls: (cp) => lookup(bs, bv, "L", cp),
27
+ jt: (cp) => {
28
+ const r = lookup(js, u.joining, null, cp);
29
+ return r && cp <= r[1] ? r[2] : "U";
30
+ },
31
+ forms: new Map(u.forms.map((r) => [r[0], r.slice(1)])),
32
+ lamAlef: new Map(u.lam_alef.map((r) => [r[0], r.slice(1)])),
33
+ mirror: new Map(u.mirror.map((r) => [r[0], r[1]])),
34
+ brackets: new Map(u.brackets.map((r) => [r[0], [r[1], r[2]]])),
35
+ };
36
+ }
37
+ const ISOLATES = new Set(["LRI", "RLI", "FSI", "PDI"]);
38
+ /** Removed before shaping's output (X9): boundary neutrals and the embedding controls, which
39
+ * this subset doesn't implement. */
40
+ const REMOVED = new Set(["BN", "LRE", "RLE", "LRO", "RLO", "PDF"]);
41
+ /** Zero-width strong marks: they take part in the bidi pass but draw nothing. */
42
+ const INVISIBLE = new Set([0x200e, 0x200f, 0x061c]);
43
+ /** §6.1: the text as clusters, letters in their joining forms, lam-alef as one ligature. */
44
+ export function shapeClusters(text, P) {
45
+ const chars = Array.from(text, (c) => c.codePointAt(0));
46
+ const types = chars.map((c) => P.jt(c));
47
+ const n = chars.length;
48
+ const near = (i, step) => {
49
+ let j = i + step;
50
+ while (j >= 0 && j < n && types[j] === "T")
51
+ j += step;
52
+ return j >= 0 && j < n ? types[j] : "U";
53
+ };
54
+ const joinsPrev = (i) => "RDC".includes(types[i]) && "DLC".includes(near(i, -1));
55
+ const joinsNext = (i) => "LDC".includes(types[i]) && "RDC".includes(near(i, 1));
56
+ const out = [];
57
+ for (let i = 0; i < n; i++) {
58
+ const c = chars[i];
59
+ const cls = P.cls(c);
60
+ if (REMOVED.has(cls))
61
+ continue;
62
+ const ch = String.fromCodePoint(c);
63
+ const last = out.at(-1);
64
+ if (cls === "NSM" && last && last.cps.length > 0) {
65
+ last.cps.push(c);
66
+ last.src += ch;
67
+ continue;
68
+ }
69
+ if (ISOLATES.has(cls) || INVISIBLE.has(c)) {
70
+ out.push({ cps: [], src: "", cls });
71
+ continue;
72
+ }
73
+ if (c === 0x0644) {
74
+ let k = i + 1;
75
+ while (k < n && types[k] === "T" && P.cls(chars[k]) === "NSM")
76
+ k++;
77
+ const lig = P.lamAlef.get(chars[k]);
78
+ if (k < n && lig) {
79
+ const form = joinsPrev(i) ? 1 : 0;
80
+ out.push({
81
+ cps: [lig[form] || lig[0], ...chars.slice(i + 1, k)],
82
+ src: String.fromCodePoint(...chars.slice(i, k + 1)),
83
+ cls,
84
+ });
85
+ i = k;
86
+ continue;
87
+ }
88
+ }
89
+ const f = P.forms.get(c);
90
+ let cp = c;
91
+ if (f) {
92
+ const p = joinsPrev(i);
93
+ const x = joinsNext(i);
94
+ const form = p && x ? 3 : p ? 1 : x ? 2 : 0;
95
+ cp = f[form] || f[0] || c;
96
+ }
97
+ out.push({ cps: [cp], src: ch, cls });
98
+ }
99
+ return out;
100
+ }
101
+ /** §6.1: the shaped text (presentation forms, logical order). */
102
+ export function shapeArabic(text, tables) {
103
+ return shapeClusters(text, prepare(tables))
104
+ .map((c) => String.fromCodePoint(...c.cps))
105
+ .join("");
106
+ }
107
+ // ---------------------------------------------------------------- UAX #9
108
+ const strong = (t) => (t === "L" ? "L" : t === "R" || t === "EN" || t === "AN" ? "R" : "");
109
+ const NI = new Set(["B", "S", "WS", "ON", "LRI", "RLI", "FSI", "PDI"]);
110
+ const MAX_DEPTH = 60;
111
+ /** §6.2: the embedding level of each cluster in a paragraph of level `p` (0 or 1). */
112
+ export function bidiLevels(clusters, p, P) {
113
+ const n = clusters.length;
114
+ const cls = clusters.map((c) => c.cls);
115
+ const levels = new Array(n).fill(p);
116
+ // BD9: each isolate initiator with its matching PDI (-1: open to the paragraph's end)
117
+ const match = new Map();
118
+ const stack = [];
119
+ let overflow = 0;
120
+ for (let i = 0; i < n; i++) {
121
+ const t = cls[i];
122
+ if (t === "LRI" || t === "RLI" || t === "FSI") {
123
+ if (overflow || stack.length >= MAX_DEPTH) {
124
+ overflow++;
125
+ cls[i] = "ON";
126
+ }
127
+ else {
128
+ stack.push(i);
129
+ match.set(i, -1);
130
+ }
131
+ }
132
+ else if (t === "PDI") {
133
+ if (overflow) {
134
+ overflow--;
135
+ cls[i] = "ON";
136
+ }
137
+ else if (stack.length)
138
+ match.set(stack.pop(), i);
139
+ }
140
+ }
141
+ const contentEnd = (i) => {
142
+ const m = match.get(i);
143
+ return m < 0 ? n : m;
144
+ };
145
+ /** The indices of the isolating run sequence from `from` to `to` (nested contents skipped). */
146
+ const sequence = (from, to) => {
147
+ const out = [];
148
+ for (let i = from; i < to; i++) {
149
+ out.push(i);
150
+ if (match.has(i)) {
151
+ const e = contentEnd(i);
152
+ if (e < n)
153
+ out.push(e);
154
+ i = e;
155
+ }
156
+ }
157
+ return out;
158
+ };
159
+ const firstStrong = (from, to) => {
160
+ for (let i = from; i < to; i++) {
161
+ const t = cls[i];
162
+ if (t === "L")
163
+ return 0;
164
+ if (t === "R" || t === "AL")
165
+ return 1;
166
+ if (match.has(i))
167
+ i = contentEnd(i);
168
+ }
169
+ return 0;
170
+ };
171
+ const run = (seq, level) => {
172
+ const t = seq.map((i) => cls[i]);
173
+ resolve(t, level, seq.map((i) => clusters[i]?.cps[0] ?? 0), P);
174
+ seq.forEach((i, k) => {
175
+ const x = t[k];
176
+ levels[i] =
177
+ level % 2 === 0
178
+ ? level + (x === "R" ? 1 : x === "AN" || x === "EN" ? 2 : 0)
179
+ : level + (x === "L" || x === "EN" || x === "AN" ? 1 : 0);
180
+ });
181
+ for (const i of seq) {
182
+ if (!match.has(i))
183
+ continue;
184
+ const kind = cls[i] === "FSI" ? (firstStrong(i + 1, contentEnd(i)) ? "RLI" : "LRI") : cls[i];
185
+ const odd = kind === "RLI";
186
+ const inner = level + 1 + (level % 2 === (odd ? 1 : 0) ? 1 : 0);
187
+ run(sequence(i + 1, contentEnd(i)), inner);
188
+ }
189
+ };
190
+ run(sequence(0, n), p);
191
+ return levels;
192
+ }
193
+ /** W1-W7, N0-N2 on one isolating run sequence's types `t` (in place). */
194
+ function resolve(t, level, cps, P) {
195
+ const n = t.length;
196
+ const e = level % 2 ? "R" : "L";
197
+ const sos = e;
198
+ // W1
199
+ for (let k = 0; k < n; k++)
200
+ if (t[k] === "NSM")
201
+ t[k] = k === 0 ? sos : ISOLATES.has(t[k - 1]) ? "ON" : t[k - 1];
202
+ // W2, W3
203
+ let last = sos;
204
+ for (let k = 0; k < n; k++) {
205
+ const x = t[k];
206
+ if (x === "L" || x === "R" || x === "AL")
207
+ last = x;
208
+ else if (x === "EN" && last === "AL")
209
+ t[k] = "AN";
210
+ }
211
+ for (let k = 0; k < n; k++)
212
+ if (t[k] === "AL")
213
+ t[k] = "R";
214
+ // W4
215
+ for (let k = 1; k < n - 1; k++) {
216
+ const a = t[k - 1];
217
+ const b = t[k + 1];
218
+ if (t[k] === "ES" && a === "EN" && b === "EN")
219
+ t[k] = "EN";
220
+ else if (t[k] === "CS" && a === b && (a === "EN" || a === "AN"))
221
+ t[k] = a;
222
+ }
223
+ // W5
224
+ for (let k = 0; k < n; k++) {
225
+ if (t[k] !== "ET")
226
+ continue;
227
+ let j = k;
228
+ while (j < n && t[j] === "ET")
229
+ j++;
230
+ if (t[k - 1] === "EN" || t[j] === "EN")
231
+ for (let q = k; q < j; q++)
232
+ t[q] = "EN";
233
+ k = j - 1;
234
+ }
235
+ // W6
236
+ for (let k = 0; k < n; k++)
237
+ if (t[k] === "ES" || t[k] === "ET" || t[k] === "CS")
238
+ t[k] = "ON";
239
+ // W7
240
+ last = sos;
241
+ for (let k = 0; k < n; k++) {
242
+ const x = t[k];
243
+ if (x === "L" || x === "R")
244
+ last = x;
245
+ else if (x === "EN" && last === "L")
246
+ t[k] = "L";
247
+ }
248
+ // N0: bracket pairs (BD16), in the order of their opening brackets
249
+ const canon = (cp) => (cp === 0x2329 ? 0x3008 : cp === 0x232a ? 0x3009 : cp);
250
+ const pairs = [];
251
+ const open = [];
252
+ for (let k = 0; k < n; k++) {
253
+ const b = P.brackets.get(cps[k]);
254
+ if (!b || t[k] !== "ON")
255
+ continue;
256
+ if (b[1] === "o") {
257
+ if (open.length === 63)
258
+ break;
259
+ open.push([canon(b[0]), k]);
260
+ }
261
+ else
262
+ for (let s = open.length - 1; s >= 0; s--)
263
+ if (open[s][0] === canon(cps[k])) {
264
+ pairs.push([open[s][1], k]);
265
+ open.length = s;
266
+ break;
267
+ }
268
+ }
269
+ pairs.sort((a, b) => a[0] - b[0]);
270
+ const opp = e === "L" ? "R" : "L";
271
+ for (const [o, c] of pairs) {
272
+ let hasE = false;
273
+ let hasOpp = false;
274
+ for (let k = o + 1; k < c; k++) {
275
+ const s = strong(t[k]);
276
+ if (s === e)
277
+ hasE = true;
278
+ else if (s === opp)
279
+ hasOpp = true;
280
+ }
281
+ let dir = "";
282
+ if (hasE)
283
+ dir = e;
284
+ else if (hasOpp) {
285
+ let before = sos;
286
+ for (let k = o - 1; k >= 0; k--) {
287
+ const s = strong(t[k]);
288
+ if (s) {
289
+ before = s;
290
+ break;
291
+ }
292
+ }
293
+ dir = before === opp ? opp : e;
294
+ }
295
+ if (dir) {
296
+ t[o] = dir;
297
+ t[c] = dir;
298
+ }
299
+ }
300
+ // N1, N2
301
+ for (let k = 0; k < n; k++) {
302
+ if (!NI.has(t[k]))
303
+ continue;
304
+ let j = k;
305
+ while (j < n && NI.has(t[j]))
306
+ j++;
307
+ const before = k === 0 ? sos : strong(t[k - 1]);
308
+ const after = j === n ? sos : strong(t[j]);
309
+ const dir = before === after ? before : e;
310
+ for (let q = k; q < j; q++)
311
+ t[q] = dir;
312
+ k = j - 1;
313
+ }
314
+ }
315
+ /** L1-L2 and L4 for one line (`line`: cluster indices in logical order): the indices in visual
316
+ * order, controls left out, each cluster's code points with mirroring applied, and whether its
317
+ * level is odd (right to left). */
318
+ export function reorderLine(line, clusters, levels, p, P) {
319
+ const lv = line.map((i) => levels[i]);
320
+ // L1: segment separators, and whitespace before them or at the end of the line
321
+ let trailing = true;
322
+ for (let k = line.length - 1; k >= 0; k--) {
323
+ const t = clusters[line[k]]?.cls;
324
+ if (t === "S" || t === "B") {
325
+ lv[k] = p;
326
+ trailing = true;
327
+ }
328
+ else if (t === "WS" || ISOLATES.has(t)) {
329
+ if (trailing)
330
+ lv[k] = p;
331
+ }
332
+ else
333
+ trailing = false;
334
+ }
335
+ // L2
336
+ const order = line.map((_, k) => k);
337
+ const high = Math.max(p, ...lv);
338
+ const low = Math.min(high, ...lv);
339
+ const lowOdd = low % 2 ? low : low + 1;
340
+ for (let l = high; l >= lowOdd; l--)
341
+ for (let k = 0; k < order.length; k++) {
342
+ if (lv[order[k]] < l)
343
+ continue;
344
+ let j = k;
345
+ while (j < order.length && lv[order[j]] >= l)
346
+ j++;
347
+ order.splice(k, j - k, ...order.slice(k, j).reverse());
348
+ k = j - 1;
349
+ }
350
+ const out = [];
351
+ for (const k of order) {
352
+ const index = line[k];
353
+ const c = clusters[index];
354
+ if (c.cps.length === 0)
355
+ continue;
356
+ const m = lv[k] % 2 ? P.mirror.get(c.cps[0]) : undefined;
357
+ out.push({
358
+ index,
359
+ cps: m === undefined ? c.cps : [m, ...c.cps.slice(1)],
360
+ odd: lv[k] % 2 === 1,
361
+ });
362
+ }
363
+ return out;
364
+ }
365
+ /** §6.2: one line of text, shaped and in visual (left to right) order, in a paragraph of level `p`. */
366
+ export function visualLine(text, p, tables) {
367
+ const P = prepare(tables);
368
+ const clusters = shapeClusters(text, P);
369
+ const levels = bidiLevels(clusters, p, P);
370
+ return reorderLine(clusters.map((_, i) => i), clusters, levels, p, P)
371
+ .map((c) => String.fromCodePoint(...c.cps))
372
+ .join("");
373
+ }
@@ -0,0 +1,77 @@
1
+ import { type UnicodeTables } from "./arabic.ts";
2
+ export interface FontMetrics {
3
+ name: string;
4
+ first_char: number;
5
+ widths: number[];
6
+ ascent: number;
7
+ descent: number;
8
+ cap_height: number;
9
+ bbox: number[];
10
+ italic_angle: number;
11
+ stem_v: number;
12
+ flags: number;
13
+ }
14
+ /** spec/pdf/arabic-metrics.json */
15
+ export interface ArabicMetrics extends Omit<FontMetrics, "first_char" | "widths"> {
16
+ /** [code point, glyph id, advance, yMin, yMax] */
17
+ glyphs: number[][];
18
+ /** [code point, horizontal center] of the zero-advance marks */
19
+ marks: number[][];
20
+ /** [glyph id, the text it stands for, as hex code points] */
21
+ to_unicode: Array<[number, string]>;
22
+ }
23
+ /** spec/pdf.md §2a-§2b: the Arabic font subset, its metrics and the Unicode tables. */
24
+ export interface ArabicAssets {
25
+ font: Uint8Array;
26
+ metrics: ArabicMetrics;
27
+ unicode: UnicodeTables;
28
+ }
29
+ /** spec/pdf.md §2: the files in spec/pdf/, as the caller read them. Without `arabic`, text
30
+ * outside WinAnsi is drawn as "?" and nothing is reordered. */
31
+ export interface PdfAssets {
32
+ font: Uint8Array;
33
+ metrics: FontMetrics;
34
+ icc: Uint8Array;
35
+ arabic?: ArabicAssets;
36
+ }
37
+ export interface PdfAttachment {
38
+ name: string;
39
+ mime: string;
40
+ /** PDF/A-3 AFRelationship: the evidence (`Data`), or the same report in another form. */
41
+ relationship: "Data" | "Alternative" | "Source";
42
+ description: string;
43
+ bytes: Uint8Array;
44
+ }
45
+ export interface PdfInput {
46
+ title: string;
47
+ markdown: string;
48
+ attachments: PdfAttachment[];
49
+ /** ISO-8601 UTC with Z: the signing time. */
50
+ at: string;
51
+ /** The drawn text's language: "ar" lays every line out right to left (§6). Default "en". */
52
+ lang?: "en" | "ar";
53
+ }
54
+ /** spec/pdf.md §3: the identity's self-signed X.509 certificate (v1, CN = its did:key). */
55
+ export declare function pdfCertificate(seed: Uint8Array): Uint8Array;
56
+ /** spec/pdf.md: the report as a signed PDF/A-3b file. `seed` is the signer's Ed25519 seed. */
57
+ export declare function reportPdf(input: PdfInput, seed: Uint8Array, assets: PdfAssets): Uint8Array;
58
+ export interface PdfVerification {
59
+ ok: boolean;
60
+ signer: string | null;
61
+ signed_at: string | null;
62
+ pdfa: {
63
+ ok: boolean;
64
+ problems: string[];
65
+ };
66
+ attachments: Array<{
67
+ name: string;
68
+ mime: string;
69
+ relationship: string;
70
+ sha256: string;
71
+ size: number;
72
+ }>;
73
+ problems: string[];
74
+ }
75
+ /** spec/pdf.md §4: checks the signature (the ByteRange digest and the CMS signature, against the
76
+ * certificate inside) and the PDF/A-3b structure as far as it can be checked offline. */
77
+ export declare function verifyPdf(pdf: Uint8Array): PdfVerification;