agent-first-data 0.12.0 → 0.12.2

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 (2) hide show
  1. package/dist/format.js +32 -16
  2. package/package.json +2 -2
package/dist/format.js CHANGED
@@ -284,8 +284,13 @@ function applyRedactionPolicyWithContext(value, redactionPolicy, context) {
284
284
  * original). Only secret spans change; all other bytes are preserved.
285
285
  */
286
286
  function redactUrlInStr(s, secretNames) {
287
- // Fast path + precondition: a single, whitespace-free, scheme-prefixed URL.
288
- if (!s.includes("://") || !isSingleUrl(s) || !urlParses(s)) {
287
+ // Precondition (spec): a single, whitespace-free, scheme-prefixed URL.
288
+ // The gate is scheme + no-whitespace only — NOT "parses via `new URL`". Span
289
+ // location below is purely byte-wise (we never re-serialize the URL), so a
290
+ // `new URL` gate would only diverge across languages — it rejects inputs
291
+ // (ports > 65535, empty host) that other languages' URL libraries accept, and
292
+ // rejecting here would silently leak secrets in the values it rejects.
293
+ if (!s.includes("://") || !isSingleUrl(s)) {
289
294
  return null;
290
295
  }
291
296
  const schemeSep = s.indexOf("://");
@@ -371,16 +376,6 @@ function formDecode(rawKey) {
371
376
  return withSpaces;
372
377
  }
373
378
  }
374
- /** True when s parses as a URL (mirrors Rust's url::Url::parse check). */
375
- function urlParses(s) {
376
- try {
377
- new URL(s);
378
- return true;
379
- }
380
- catch {
381
- return false;
382
- }
383
- }
384
379
  /**
385
380
  * True when s begins with a URL scheme (ALPHA *(ALPHA / DIGIT / "+" / "-" /
386
381
  * ".") "://") and contains no ASCII whitespace — i.e. a single bare URL, not a
@@ -631,6 +626,27 @@ function formatRfc3339Ms(ms) {
631
626
  return String(ms);
632
627
  }
633
628
  }
629
+ /**
630
+ * Round to `digits` decimals using round-half-to-even (banker's rounding) and
631
+ * format with a fixed decimal count. `Number.toFixed` rounds half away from
632
+ * zero, which diverges from the printf `%.1f` used by Rust/Go/Python on exact
633
+ * ties (e.g. 1280 bytes = 1.25 KB → "1.2KB", not "1.3KB").
634
+ */
635
+ function toFixedHalfEven(x, digits) {
636
+ const factor = 10 ** digits;
637
+ const scaled = x * factor;
638
+ const floor = Math.floor(scaled);
639
+ const diff = scaled - floor;
640
+ const eps = 1e-9;
641
+ let rounded;
642
+ if (diff > 0.5 + eps)
643
+ rounded = floor + 1;
644
+ else if (diff < 0.5 - eps)
645
+ rounded = floor;
646
+ else
647
+ rounded = floor % 2 === 0 ? floor : floor + 1;
648
+ return (rounded / factor).toFixed(digits);
649
+ }
634
650
  function formatBytesHuman(bytes) {
635
651
  const KB = 1024;
636
652
  const MB = KB * 1024;
@@ -639,13 +655,13 @@ function formatBytesHuman(bytes) {
639
655
  const sign = bytes < 0 ? "-" : "";
640
656
  const b = Math.abs(bytes);
641
657
  if (b >= TB)
642
- return `${sign}${(b / TB).toFixed(1)}TB`;
658
+ return `${sign}${toFixedHalfEven(b / TB, 1)}TB`;
643
659
  if (b >= GB)
644
- return `${sign}${(b / GB).toFixed(1)}GB`;
660
+ return `${sign}${toFixedHalfEven(b / GB, 1)}GB`;
645
661
  if (b >= MB)
646
- return `${sign}${(b / MB).toFixed(1)}MB`;
662
+ return `${sign}${toFixedHalfEven(b / MB, 1)}MB`;
647
663
  if (b >= KB)
648
- return `${sign}${(b / KB).toFixed(1)}KB`;
664
+ return `${sign}${toFixedHalfEven(b / KB, 1)}KB`;
649
665
  return `${bytes}B`;
650
666
  }
651
667
  function formatWithCommas(n) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-first-data",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "description": "A naming convention that lets AI agents understand your data without being told what it means.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -26,7 +26,7 @@
26
26
  ],
27
27
  "scripts": {
28
28
  "build": "tsc",
29
- "test": "tsx --test src/*.test.ts"
29
+ "test": "tsx --test src/*.test.ts examples/agent_cli.ts"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "^25.2.3",