agent-first-data 0.16.0 → 0.17.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 +1 -1
- package/assets/protocol-v1.schema.json +2 -19
- package/assets/registry.json +2 -11
- package/assets/skills/agent-first-data/references/registry.json +2 -11
- package/assets/skills/agent-first-data/references/rules.md +13 -12
- package/dist/format.d.ts +30 -33
- package/dist/format.js +84 -197
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ console.log(outputJson(event.toJSON()));
|
|
|
17
17
|
console.log(outputPlain(event.toJSON()));
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
Useful names use TypeScript casing: `outputJson`, `outputYaml`, `outputPlain`, `outputOptionsForPolicy`, `redactedValue`, `redactUrlSecrets`, `
|
|
20
|
+
Useful names use TypeScript casing: `outputJson`, `outputYaml`, `outputPlain`, `outputOptionsForPolicy`, `redactedValue`, `redactUrlSecrets`, `normalizeUtcOffset`, `isValidRfc3339Date`, `isValidRfc3339Time`, `decodeProtocolEvent`, `cliParseOutput`, `cliParseLogFilters`, `cliOutput`, `buildCliError`, `buildCliVersion`, and `cliHandleVersionOrContinue`.
|
|
21
21
|
|
|
22
22
|
Skill admin and stream redirection are not re-exported from the package root; import them from their own subpaths:
|
|
23
23
|
|
|
@@ -47,13 +47,7 @@
|
|
|
47
47
|
"type": "object",
|
|
48
48
|
"properties": {
|
|
49
49
|
"kind": {"const": "progress"},
|
|
50
|
-
"progress":
|
|
51
|
-
"type": "object",
|
|
52
|
-
"properties": {
|
|
53
|
-
"message": {"type": "string", "minLength": 1}
|
|
54
|
-
},
|
|
55
|
-
"additionalProperties": true
|
|
56
|
-
},
|
|
50
|
+
"progress": true,
|
|
57
51
|
"trace": {"$ref": "#/$defs/trace"}
|
|
58
52
|
},
|
|
59
53
|
"required": ["kind", "progress"],
|
|
@@ -63,18 +57,7 @@
|
|
|
63
57
|
"type": "object",
|
|
64
58
|
"properties": {
|
|
65
59
|
"kind": {"const": "log"},
|
|
66
|
-
"log":
|
|
67
|
-
"type": "object",
|
|
68
|
-
"properties": {
|
|
69
|
-
"message": {"type": "string", "minLength": 1},
|
|
70
|
-
"level": {"enum": ["debug", "info", "warn", "error"]},
|
|
71
|
-
"code": false
|
|
72
|
-
},
|
|
73
|
-
"not": {
|
|
74
|
-
"required": ["code"]
|
|
75
|
-
},
|
|
76
|
-
"additionalProperties": true
|
|
77
|
-
},
|
|
60
|
+
"log": true,
|
|
78
61
|
"trace": {"$ref": "#/$defs/trace"}
|
|
79
62
|
},
|
|
80
63
|
"required": ["kind", "log"],
|
package/assets/registry.json
CHANGED
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
"unit": "bcp47_language_tag",
|
|
133
133
|
"formatting": {"strip_key": false, "plain_yaml": "pass_through"},
|
|
134
134
|
"redaction": {"mode": "none"},
|
|
135
|
-
"constraints": {"
|
|
135
|
+
"constraints": {"bcp47": true}
|
|
136
136
|
},
|
|
137
137
|
{
|
|
138
138
|
"suffix": "_utc_offset",
|
|
@@ -152,18 +152,9 @@
|
|
|
152
152
|
"redaction": {"mode": "none"},
|
|
153
153
|
"constraints": {"integer": true, "minimum": 0}
|
|
154
154
|
},
|
|
155
|
-
{
|
|
156
|
-
"suffix": "_size",
|
|
157
|
-
"category": "size",
|
|
158
|
-
"json_types": ["string"],
|
|
159
|
-
"unit": "byte_size_input",
|
|
160
|
-
"formatting": {"strip_key": false, "plain_yaml": "pass_through"},
|
|
161
|
-
"redaction": {"mode": "none"},
|
|
162
|
-
"constraints": {"parse_size_units": ["B", "kB", "MB", "GB", "TB", "KiB", "MiB", "GiB", "TiB"]}
|
|
163
|
-
},
|
|
164
155
|
{
|
|
165
156
|
"suffix": "_percent",
|
|
166
|
-
"category": "
|
|
157
|
+
"category": "percentage",
|
|
167
158
|
"json_types": ["number"],
|
|
168
159
|
"unit": "percent",
|
|
169
160
|
"formatting": {"strip_key": true, "plain_yaml": "append_percent"},
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
"unit": "bcp47_language_tag",
|
|
133
133
|
"formatting": {"strip_key": false, "plain_yaml": "pass_through"},
|
|
134
134
|
"redaction": {"mode": "none"},
|
|
135
|
-
"constraints": {"
|
|
135
|
+
"constraints": {"bcp47": true}
|
|
136
136
|
},
|
|
137
137
|
{
|
|
138
138
|
"suffix": "_utc_offset",
|
|
@@ -152,18 +152,9 @@
|
|
|
152
152
|
"redaction": {"mode": "none"},
|
|
153
153
|
"constraints": {"integer": true, "minimum": 0}
|
|
154
154
|
},
|
|
155
|
-
{
|
|
156
|
-
"suffix": "_size",
|
|
157
|
-
"category": "size",
|
|
158
|
-
"json_types": ["string"],
|
|
159
|
-
"unit": "byte_size_input",
|
|
160
|
-
"formatting": {"strip_key": false, "plain_yaml": "pass_through"},
|
|
161
|
-
"redaction": {"mode": "none"},
|
|
162
|
-
"constraints": {"parse_size_units": ["B", "kB", "MB", "GB", "TB", "KiB", "MiB", "GiB", "TiB"]}
|
|
163
|
-
},
|
|
164
155
|
{
|
|
165
156
|
"suffix": "_percent",
|
|
166
|
-
"category": "
|
|
157
|
+
"category": "percentage",
|
|
167
158
|
"json_types": ["number"],
|
|
168
159
|
"unit": "percent",
|
|
169
160
|
"formatting": {"strip_key": true, "plain_yaml": "append_percent"},
|
|
@@ -37,6 +37,10 @@ The field name is the schema. Always encode units and semantics in the field nam
|
|
|
37
37
|
| `_epoch_ns` | nanoseconds since Unix epoch as a decimal string | `created_epoch_ns: "1707868800000000000"` |
|
|
38
38
|
| `_rfc3339` | RFC 3339 date-time string | `expires_rfc3339: "2026-02-14T10:30:00Z"` |
|
|
39
39
|
|
|
40
|
+
Integer vs string is not uniform across siblings: `_epoch_s` and `_epoch_ms` are JSON integers, but `_epoch_ns` is a decimal **string** because nanoseconds exceed the 2⁵³−1 safe-integer range. The same rule applies to large `_sats`/`_msats` (integer when safe, decimal string when not). Writing `_epoch_ns` as a bare JSON number silently loses precision — `afdata lint` rejects it (`suffix_type_mismatch`).
|
|
41
|
+
|
|
42
|
+
`_rfc3339` needs a **mandatory** offset: `YYYY-MM-DDThh:mm:ss[.fff]` followed by `Z` or `±HH:MM`. A bare `2026-02-14T10:30:00` (no offset), a space instead of `T`, or a trailing IANA name (`...Asia/Shanghai`) is rejected by `afdata lint`. `afdata lint` also type-checks the numeric suffixes (durations `_s`/`_ms`/…, currency `_cents`/`_micro`/`_jpy`) and rejects a `_url` with internal whitespace or bare `user:pass@host` credentials.
|
|
43
|
+
|
|
40
44
|
### Strict string formats
|
|
41
45
|
|
|
42
46
|
| Suffix | Format | Example |
|
|
@@ -46,7 +50,7 @@ The field name is the schema. Always encode units and semantics in the field nam
|
|
|
46
50
|
| `_rfc3339_date` | RFC 3339 full-date string | `invoice_due_rfc3339_date: "2026-06-13"` |
|
|
47
51
|
| `_rfc3339_time` | RFC 3339 partial-time string | `market_open_rfc3339_time: "09:30:00"` |
|
|
48
52
|
|
|
49
|
-
`*_bcp47` identifies a BCP-47 language tag string. AFDATA does not
|
|
53
|
+
`*_bcp47` identifies a BCP-47 language tag string. AFDATA validates structure (hyphen-separated subtags, 2–3 letter primary language), so the POSIX form `zh_CN` and an over-long primary like `chinese` are rejected; use `zh-CN`. It does not check the IANA registry, so a well-formed-but-unregistered tag like `zz-ZZ` still passes. `is_valid_bcp47` and `afdata lint` apply this check.
|
|
50
54
|
|
|
51
55
|
`*_utc_offset` identifies a fixed UTC offset. Canonical persisted and structured output values are `"UTC"` or `±HH:MM`, with `HH` in `00..23` and `MM` in `00..59`; zero offsets normalize to `"UTC"`. This is not an IANA timezone name, DST rule, or timezone database field.
|
|
52
56
|
|
|
@@ -63,11 +67,8 @@ Avoid magic string sentinels such as `"auto"` inside strict-format fields. If a
|
|
|
63
67
|
| Suffix | Example |
|
|
64
68
|
|:-------|:--------|
|
|
65
69
|
| `_bytes` | `payload_bytes: 456789` (non-negative integer) |
|
|
66
|
-
| `_size` | `buffer_size: "10MiB"` or `"10MB"` (config files only, human-readable) |
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
`parse_size("10MiB")` → `10485760`; `parse_size("10MB")` → `10000000`. Returns null for invalid or negative input.
|
|
71
|
+
Byte sizes are always integer `_bytes`, in config and output alike. There is no unit-in-value size string: never write `buffer_size: "10MiB"`. Encode the unit in the key (`buffer_bytes: 10485760`), the same way durations use `timeout_s: 30`.
|
|
71
72
|
|
|
72
73
|
### Percentage
|
|
73
74
|
|
|
@@ -75,6 +76,8 @@ Avoid magic string sentinels such as `"auto"` inside strict-format fields. If a
|
|
|
75
76
|
|:-------|:--------|
|
|
76
77
|
| `_percent` | `cpu_percent: 85` |
|
|
77
78
|
|
|
79
|
+
Value is in units of percent: `1` = 1%, `0.2` = 0.2%, `85` = 85%. Decimals, negatives, and values >100 are all valid; no fixed range. `%` is exactly 0.01, so `_percent` is never a 0–1 fraction — if the underlying ratio is `0.999`, multiply by 100 and write `success_percent: 99.9`. Writing `0.85` for 85% is a producer-side conversion bug, not a convention ambiguity.
|
|
80
|
+
|
|
78
81
|
### Currency
|
|
79
82
|
|
|
80
83
|
Bitcoin:
|
|
@@ -150,7 +153,6 @@ ORM struct fields preserve the suffix: `duration_ms: i64`, not `duration: i64`.
|
|
|
150
153
|
| `latency: 142` | `latency_ms: 142` | seconds? milliseconds? |
|
|
151
154
|
| `api_key: "sk-..."` | `api_key_secret: "sk-..."` | won't be auto-redacted |
|
|
152
155
|
| `cpu: 85` | `cpu_percent: 85` | 85 what? |
|
|
153
|
-
| `buffer: "10MiB"` | `buffer_size: "10MiB"` | only `_size` gets parsed |
|
|
154
156
|
|
|
155
157
|
---
|
|
156
158
|
|
|
@@ -174,7 +176,7 @@ Remove recognized formatting suffix from key. Longest match first, exact lowerca
|
|
|
174
176
|
4. `_msats`, `_sats`, `_bytes`, `_percent`, `_secret`
|
|
175
177
|
5. `_jpy`, `_ns`, `_us`, `_ms`, `_s`
|
|
176
178
|
|
|
177
|
-
`
|
|
179
|
+
`_bcp47`, `_utc_offset`, `_rfc3339_date`, and `_rfc3339_time` are NOT stripped (pass through). If two keys collide after stripping, both revert to original key AND raw value (no formatting). Redaction runs before collision handling, so fallback never restores a secret.
|
|
178
180
|
|
|
179
181
|
### Value formatting (YAML and Plain)
|
|
180
182
|
|
|
@@ -184,7 +186,6 @@ Remove recognized formatting suffix from key. Longest match first, exact lowerca
|
|
|
184
186
|
- `_epoch_ms`/`_epoch_s`/decimal-string `_epoch_ns` → RFC 3339 (negative = pre-1970)
|
|
185
187
|
- `_rfc3339` → pass through
|
|
186
188
|
- `_bytes` → human-readable (`456789` → `446.1KiB`); negative and fractional byte values fall through raw
|
|
187
|
-
- `_size` → pass through
|
|
188
189
|
- `_percent` → append `%`
|
|
189
190
|
- `_msats` → `{n}msats`, `_sats` → `{n}sats`
|
|
190
191
|
- `_usd_cents` → `$X.XX`, `_eur_cents` → `€X.XX`, `_jpy` → `¥X,XXX`, `_{code}_cents` → `X.XX CODE`, `_{code}_micro` → `X.XXXXXX CODE` where `code` is 3-4 ASCII letters
|
|
@@ -258,7 +259,7 @@ Startup payload fields are tool-defined; `config` is recommended, while `version
|
|
|
258
259
|
|
|
259
260
|
All use `kind` plus the same-named payload and optional `trace`. Do not split protocol events across `stdout` and `stderr`.
|
|
260
261
|
|
|
261
|
-
Base validators enforce mandatory envelope/error/lifecycle rules. Strict validators additionally require object-valued `trace` on every event
|
|
262
|
+
Base validators enforce mandatory envelope/error/lifecycle rules. Strict validators additionally require object-valued `trace` on every event and `retryable` on every error. Log and progress payloads remain tool-defined in both profiles. Use strict validation before claiming compliance with all recommendations.
|
|
262
263
|
|
|
263
264
|
---
|
|
264
265
|
|
|
@@ -298,11 +299,11 @@ let span = info_span!("request", request_id = %uuid);
|
|
|
298
299
|
let _guard = span.enter();
|
|
299
300
|
```
|
|
300
301
|
|
|
301
|
-
For Go, Python, and TypeScript: emit span fields explicitly in each log
|
|
302
|
+
For Go, Python, and TypeScript: emit span fields explicitly in each tool-defined log payload.
|
|
302
303
|
|
|
303
304
|
### Output fields
|
|
304
305
|
|
|
305
|
-
|
|
306
|
+
Log payloads have no required or reserved fields. Traditional logging adapters commonly add `message` and `level` (debug/info/warn/error), plus span and event fields, but those names and meanings are adapter conventions rather than AFDATA protocol requirements. Projects that need timestamps add `timestamp_epoch_ms` explicitly.
|
|
306
307
|
|
|
307
308
|
Log redaction is **by field name** (the same `_secret`/`_url` rule as all output), applied when the line is emitted. Name the secret field — `info!(api_key_secret = %key)` — rather than logging a whole object by its `Debug`/string rendering, which hides the inner field names from redaction. For structured/nested secret-bearing data, build a value, apply redaction through output formatters or redacted_value(), then emit via the standard formatting helpers — do not pass the struct to a `?`/`%`-rendered log field.
|
|
308
309
|
|
|
@@ -340,7 +341,7 @@ Use this checklist when the skill is evaluating a change, not just documenting c
|
|
|
340
341
|
3. Require secret-bearing values to be named with `_secret` or configured exact secret names before serialization. Do not rely on arbitrary free-text scanning or `Debug`/string-rendered objects.
|
|
341
342
|
4. Run `afdata lint` for JSON/JSONL samples, JSON Schema, MCP schemas, or serialized outputs when available; run `afdata validate` for finite protocol events/streams. If unavailable, report the skipped check.
|
|
342
343
|
5. Before changing an external project's public API, wire format, database schema, or persisted field names, report the compatibility impact and request approval before editing.
|
|
343
|
-
6.
|
|
344
|
+
6. Byte sizes use integer `_bytes` everywhere, config included (`buffer_bytes: 10485760`, never `buffer_size: "10MiB"`)
|
|
344
345
|
7. Environment variables follow `UPPER_SNAKE_CASE` with the same suffixes
|
|
345
346
|
8. One-time CLI output uses `json_log()`/`CliEmitter` + output helpers; long-running services use `afdata_tracing::try_init()` (Rust) to capture via tracing; other languages emit log events explicitly via builders
|
|
346
347
|
9. Database columns use AFDATA suffixes on generic types (`duration_ms INTEGER`, not `duration INTEGER`); native types like `TIMESTAMPTZ` don't need suffixes
|
package/dist/format.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* AFDATA output formatting and protocol templates.
|
|
3
3
|
*
|
|
4
4
|
* Public APIs include protocol event builders, redactedValue (covers _secret
|
|
5
|
-
* and _url fields), output formatters, redactUrlSecrets,
|
|
6
|
-
* normalizeUtcOffset, isValidRfc3339Date, isValidRfc3339Time,
|
|
5
|
+
* and _url fields), output formatters, redactUrlSecrets,
|
|
6
|
+
* normalizeUtcOffset, isValidRfc3339Date, isValidRfc3339Time, isValidRfc3339, isValidBcp47,
|
|
7
7
|
* RedactionPolicy, OutputStyle, and OutputOptions.
|
|
8
8
|
*/
|
|
9
9
|
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
@@ -54,30 +54,19 @@ export declare class JsonErrorBuilder {
|
|
|
54
54
|
build(): Event;
|
|
55
55
|
}
|
|
56
56
|
export declare class JsonProgressBuilder {
|
|
57
|
-
private readonly
|
|
58
|
-
private extensionFields;
|
|
57
|
+
private readonly payload;
|
|
59
58
|
private traceValue;
|
|
60
59
|
private issues;
|
|
61
|
-
constructor(
|
|
62
|
-
field(name: string, value: JsonValue): this;
|
|
63
|
-
fields(obj: unknown): this;
|
|
64
|
-
extend(obj: unknown): this;
|
|
60
|
+
constructor(payload: JsonValue);
|
|
65
61
|
trace(value: Record<string, JsonValue> | undefined): this;
|
|
66
|
-
private isReservedProgressField;
|
|
67
62
|
build(): Event;
|
|
68
63
|
}
|
|
69
64
|
export declare class JsonLogBuilder {
|
|
70
|
-
private readonly
|
|
71
|
-
private readonly message;
|
|
72
|
-
private extensionFields;
|
|
65
|
+
private readonly payload;
|
|
73
66
|
private traceValue;
|
|
74
67
|
private issues;
|
|
75
|
-
constructor(
|
|
76
|
-
field(name: string, value: JsonValue): this;
|
|
77
|
-
fields(obj: unknown): this;
|
|
78
|
-
extend(obj: unknown): this;
|
|
68
|
+
constructor(payload: JsonValue);
|
|
79
69
|
trace(value: Record<string, JsonValue> | undefined): this;
|
|
80
|
-
private isReservedLogField;
|
|
81
70
|
build(): Event;
|
|
82
71
|
}
|
|
83
72
|
/** Fluent builder for result events. */
|
|
@@ -85,9 +74,9 @@ export declare function jsonResult(payload: JsonValue): JsonResultBuilder;
|
|
|
85
74
|
/** Fluent builder for error events. */
|
|
86
75
|
export declare function jsonError(code: string, message: string): JsonErrorBuilder;
|
|
87
76
|
/** Fluent builder for progress events. */
|
|
88
|
-
export declare function jsonProgress(
|
|
77
|
+
export declare function jsonProgress(payload: JsonValue): JsonProgressBuilder;
|
|
89
78
|
/** Fluent builder for log events. */
|
|
90
|
-
export declare function jsonLog(
|
|
79
|
+
export declare function jsonLog(payload: JsonValue): JsonLogBuilder;
|
|
91
80
|
/** Validate one protocol event envelope. `strict` also enforces the recommended strict protocol profile (default true). */
|
|
92
81
|
export declare function validateProtocolEvent(event: unknown, strict?: boolean): void;
|
|
93
82
|
/** Validate finite CLI lifecycle: (log | progress)* -> exactly one terminal. `strict` also enforces the recommended strict protocol profile (default true). */
|
|
@@ -108,15 +97,12 @@ export type DecodedError = {
|
|
|
108
97
|
};
|
|
109
98
|
export type DecodedProgress = {
|
|
110
99
|
kind: "progress";
|
|
111
|
-
|
|
112
|
-
fields: Record<string, JsonValue>;
|
|
100
|
+
progress: JsonValue;
|
|
113
101
|
trace?: Record<string, JsonValue>;
|
|
114
102
|
};
|
|
115
103
|
export type DecodedLog = {
|
|
116
104
|
kind: "log";
|
|
117
|
-
|
|
118
|
-
message: string;
|
|
119
|
-
fields: Record<string, JsonValue>;
|
|
105
|
+
log: JsonValue;
|
|
120
106
|
trace?: Record<string, JsonValue>;
|
|
121
107
|
};
|
|
122
108
|
/** Discriminated union of decoded protocol events, narrow on `kind`. */
|
|
@@ -127,8 +113,7 @@ export declare class EventDecodeError extends Error {
|
|
|
127
113
|
}
|
|
128
114
|
/**
|
|
129
115
|
* Parse one protocol line (a single JSON text value), strict-validate it, and
|
|
130
|
-
* return a typed decoded event.
|
|
131
|
-
* the required ones, collected into `fields`.
|
|
116
|
+
* return a typed decoded event.
|
|
132
117
|
*/
|
|
133
118
|
export declare function decodeProtocolEvent(text: string): DecodedEvent;
|
|
134
119
|
export declare enum RedactionPolicy {
|
|
@@ -179,13 +164,6 @@ export declare function redactedValue(value: unknown, options?: {
|
|
|
179
164
|
export declare function redactUrlSecrets(url: string, options?: {
|
|
180
165
|
secretNames?: readonly string[];
|
|
181
166
|
}): string;
|
|
182
|
-
/**
|
|
183
|
-
* Parse a human-readable size string into bytes.
|
|
184
|
-
* Accepts numbers followed by explicit units. Decimal units are
|
|
185
|
-
* B/kB/MB/GB/TB; binary units are KiB/MiB/GiB/TiB.
|
|
186
|
-
* Trims whitespace and rejects ambiguous K/M/G/T units.
|
|
187
|
-
*/
|
|
188
|
-
export declare function parseSize(s: string): number | null;
|
|
189
167
|
/**
|
|
190
168
|
* Normalize a fixed UTC offset string to "UTC" or ±HH:MM.
|
|
191
169
|
* This helper handles fixed offsets only; IANA timezone names and DST rules
|
|
@@ -196,3 +174,22 @@ export declare function normalizeUtcOffset(value: string): string | null;
|
|
|
196
174
|
export declare function isValidRfc3339Date(value: string): boolean;
|
|
197
175
|
/** Return true when value is an RFC 3339 partial-time (HH:MM:SS[.fraction]). */
|
|
198
176
|
export declare function isValidRfc3339Time(value: string): boolean;
|
|
177
|
+
/**
|
|
178
|
+
* Return true when value is a complete RFC 3339 date-time, such as
|
|
179
|
+
* 2026-02-14T10:30:00Z or 2026-02-14T10:30:00.5+08:00. Composed from
|
|
180
|
+
* isValidRfc3339Date and isValidRfc3339Time: a full-date, a T/t separator, a
|
|
181
|
+
* partial-time (with optional fractional seconds), and a mandatory time-offset
|
|
182
|
+
* (Z/z or ±HH:MM with HH in 00..23 and MM in 00..59). The offset is required, so
|
|
183
|
+
* a bare 2026-02-14T10:30:00 is rejected; a space separator is rejected; and a
|
|
184
|
+
* leap second (:60) is rejected, matching isValidRfc3339Time. Non-ASCII is rejected.
|
|
185
|
+
*/
|
|
186
|
+
export declare function isValidRfc3339(value: string): boolean;
|
|
187
|
+
/**
|
|
188
|
+
* Return true when value is a structurally well-formed BCP 47 (RFC 5646) language tag.
|
|
189
|
+
* A grammar-level check, not a registry lookup: hyphen-separated ASCII-alphanumeric
|
|
190
|
+
* subtags (each 1-8 chars) whose primary subtag is a 2-3 letter language code or the
|
|
191
|
+
* x/i privateuse/grandfathered lead. Rejects the POSIX underscore form (zh_CN), empty
|
|
192
|
+
* or misplaced hyphens, non-ASCII, and out-of-range primaries such as chinese. Does not
|
|
193
|
+
* verify that subtags are registered with IANA.
|
|
194
|
+
*/
|
|
195
|
+
export declare function isValidBcp47(value: string): boolean;
|
package/dist/format.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* AFDATA output formatting and protocol templates.
|
|
3
3
|
*
|
|
4
4
|
* Public APIs include protocol event builders, redactedValue (covers _secret
|
|
5
|
-
* and _url fields), output formatters, redactUrlSecrets,
|
|
6
|
-
* normalizeUtcOffset, isValidRfc3339Date, isValidRfc3339Time,
|
|
5
|
+
* and _url fields), output formatters, redactUrlSecrets,
|
|
6
|
+
* normalizeUtcOffset, isValidRfc3339Date, isValidRfc3339Time, isValidRfc3339, isValidBcp47,
|
|
7
7
|
* RedactionPolicy, OutputStyle, and OutputOptions.
|
|
8
8
|
*/
|
|
9
9
|
// ═══════════════════════════════════════════
|
|
@@ -176,53 +176,11 @@ export class JsonErrorBuilder {
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
export class JsonProgressBuilder {
|
|
179
|
-
|
|
180
|
-
extensionFields = {};
|
|
179
|
+
payload;
|
|
181
180
|
traceValue = {};
|
|
182
181
|
issues = [];
|
|
183
|
-
constructor(
|
|
184
|
-
this.
|
|
185
|
-
if (!message || message === "")
|
|
186
|
-
this.issues.push("message must be a non-empty string");
|
|
187
|
-
}
|
|
188
|
-
field(name, value) {
|
|
189
|
-
if (this.isReservedProgressField(name)) {
|
|
190
|
-
this.issues.push(`cannot write reserved progress field ${JSON.stringify(name)}`);
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
this.extensionFields[name] = value;
|
|
194
|
-
}
|
|
195
|
-
return this;
|
|
196
|
-
}
|
|
197
|
-
fields(obj) {
|
|
198
|
-
if (!isObject(obj)) {
|
|
199
|
-
this.issues.push("fields must be a JSON object");
|
|
200
|
-
return this;
|
|
201
|
-
}
|
|
202
|
-
for (const [key, val] of Object.entries(obj)) {
|
|
203
|
-
if (this.isReservedProgressField(key)) {
|
|
204
|
-
this.issues.push(`cannot write reserved progress field ${JSON.stringify(key)}`);
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
this.extensionFields[key] = val;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return this;
|
|
211
|
-
}
|
|
212
|
-
extend(obj) {
|
|
213
|
-
if (!isObject(obj)) {
|
|
214
|
-
this.issues.push("extend must be a JSON object");
|
|
215
|
-
return this;
|
|
216
|
-
}
|
|
217
|
-
for (const [key, val] of Object.entries(obj)) {
|
|
218
|
-
if (this.isReservedProgressField(key)) {
|
|
219
|
-
this.issues.push(`cannot write reserved progress field ${JSON.stringify(key)}`);
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
this.extensionFields[key] = val;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
return this;
|
|
182
|
+
constructor(payload) {
|
|
183
|
+
this.payload = payload;
|
|
226
184
|
}
|
|
227
185
|
trace(value) {
|
|
228
186
|
if (value !== undefined) {
|
|
@@ -235,71 +193,20 @@ export class JsonProgressBuilder {
|
|
|
235
193
|
}
|
|
236
194
|
return this;
|
|
237
195
|
}
|
|
238
|
-
isReservedProgressField(name) {
|
|
239
|
-
return name === "message";
|
|
240
|
-
}
|
|
241
196
|
build() {
|
|
242
197
|
if (this.issues.length > 0) {
|
|
243
198
|
throw new EventBuildError(`Failed to build progress event: ${this.issues.join("; ")}`, this.issues);
|
|
244
199
|
}
|
|
245
|
-
const
|
|
246
|
-
progress.message = this.message;
|
|
247
|
-
const m = { kind: "progress", progress, trace: this.traceValue };
|
|
200
|
+
const m = { kind: "progress", progress: this.payload, trace: this.traceValue };
|
|
248
201
|
return new Event(m);
|
|
249
202
|
}
|
|
250
203
|
}
|
|
251
204
|
export class JsonLogBuilder {
|
|
252
|
-
|
|
253
|
-
message;
|
|
254
|
-
extensionFields = {};
|
|
205
|
+
payload;
|
|
255
206
|
traceValue = {};
|
|
256
207
|
issues = [];
|
|
257
|
-
constructor(
|
|
258
|
-
this.
|
|
259
|
-
this.message = message;
|
|
260
|
-
if (!message || message === "")
|
|
261
|
-
this.issues.push("message must be a non-empty string");
|
|
262
|
-
if (!isValidLogLevel(level))
|
|
263
|
-
this.issues.push(`level must be one of debug, info, warn, error`);
|
|
264
|
-
}
|
|
265
|
-
field(name, value) {
|
|
266
|
-
if (this.isReservedLogField(name)) {
|
|
267
|
-
this.issues.push(`cannot write reserved log field ${JSON.stringify(name)}`);
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
this.extensionFields[name] = value;
|
|
271
|
-
}
|
|
272
|
-
return this;
|
|
273
|
-
}
|
|
274
|
-
fields(obj) {
|
|
275
|
-
if (!isObject(obj)) {
|
|
276
|
-
this.issues.push("fields must be a JSON object");
|
|
277
|
-
return this;
|
|
278
|
-
}
|
|
279
|
-
for (const [key, val] of Object.entries(obj)) {
|
|
280
|
-
if (this.isReservedLogField(key)) {
|
|
281
|
-
this.issues.push(`cannot write reserved log field ${JSON.stringify(key)}`);
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
this.extensionFields[key] = val;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
return this;
|
|
288
|
-
}
|
|
289
|
-
extend(obj) {
|
|
290
|
-
if (!isObject(obj)) {
|
|
291
|
-
this.issues.push("extend must be a JSON object");
|
|
292
|
-
return this;
|
|
293
|
-
}
|
|
294
|
-
for (const [key, val] of Object.entries(obj)) {
|
|
295
|
-
if (this.isReservedLogField(key)) {
|
|
296
|
-
this.issues.push(`cannot write reserved log field ${JSON.stringify(key)}`);
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
this.extensionFields[key] = val;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
return this;
|
|
208
|
+
constructor(payload) {
|
|
209
|
+
this.payload = payload;
|
|
303
210
|
}
|
|
304
211
|
trace(value) {
|
|
305
212
|
if (value !== undefined) {
|
|
@@ -312,17 +219,11 @@ export class JsonLogBuilder {
|
|
|
312
219
|
}
|
|
313
220
|
return this;
|
|
314
221
|
}
|
|
315
|
-
isReservedLogField(name) {
|
|
316
|
-
return name === "message" || name === "level" || name === "code";
|
|
317
|
-
}
|
|
318
222
|
build() {
|
|
319
223
|
if (this.issues.length > 0) {
|
|
320
224
|
throw new EventBuildError(`Failed to build log event: ${this.issues.join("; ")}`, this.issues);
|
|
321
225
|
}
|
|
322
|
-
const
|
|
323
|
-
log.level = this.level;
|
|
324
|
-
log.message = this.message;
|
|
325
|
-
const m = { kind: "log", log, trace: this.traceValue };
|
|
226
|
+
const m = { kind: "log", log: this.payload, trace: this.traceValue };
|
|
326
227
|
return new Event(m);
|
|
327
228
|
}
|
|
328
229
|
}
|
|
@@ -335,15 +236,12 @@ export function jsonError(code, message) {
|
|
|
335
236
|
return new JsonErrorBuilder(code, message);
|
|
336
237
|
}
|
|
337
238
|
/** Fluent builder for progress events. */
|
|
338
|
-
export function jsonProgress(
|
|
339
|
-
return new JsonProgressBuilder(
|
|
239
|
+
export function jsonProgress(payload) {
|
|
240
|
+
return new JsonProgressBuilder(payload);
|
|
340
241
|
}
|
|
341
242
|
/** Fluent builder for log events. */
|
|
342
|
-
export function jsonLog(
|
|
343
|
-
return new JsonLogBuilder(
|
|
344
|
-
}
|
|
345
|
-
function isValidLogLevel(level) {
|
|
346
|
-
return level === "debug" || level === "info" || level === "warn" || level === "error";
|
|
243
|
+
export function jsonLog(payload) {
|
|
244
|
+
return new JsonLogBuilder(payload);
|
|
347
245
|
}
|
|
348
246
|
/** Validate one protocol event envelope. `strict` also enforces the recommended strict protocol profile (default true). */
|
|
349
247
|
export function validateProtocolEvent(event, strict = true) {
|
|
@@ -372,10 +270,6 @@ export function validateProtocolEvent(event, strict = true) {
|
|
|
372
270
|
return;
|
|
373
271
|
if (!isObject(event.trace))
|
|
374
272
|
throw new Error("event.trace is required in strict mode");
|
|
375
|
-
if (kind === "log")
|
|
376
|
-
validateStrictLog(event.log);
|
|
377
|
-
if (kind === "progress")
|
|
378
|
-
validateStrictProgress(event.progress);
|
|
379
273
|
if (kind === "error")
|
|
380
274
|
validateStrictError(event.error);
|
|
381
275
|
}
|
|
@@ -418,25 +312,6 @@ export function validateProtocolStream(events, strict = true) {
|
|
|
418
312
|
throw new Error("event stream must contain exactly one terminal result or error");
|
|
419
313
|
}
|
|
420
314
|
}
|
|
421
|
-
function validateStrictLog(payload) {
|
|
422
|
-
if (!isObject(payload))
|
|
423
|
-
throw new Error("event.log must be a JSON object in strict mode");
|
|
424
|
-
// 0.16: log payload MUST NOT contain code field
|
|
425
|
-
if ("code" in payload) {
|
|
426
|
-
throw new Error("event.log.code is not allowed in strict mode");
|
|
427
|
-
}
|
|
428
|
-
if (typeof payload.message !== "string" || payload.message === "") {
|
|
429
|
-
throw new Error("event.log.message must be a non-empty string in strict mode");
|
|
430
|
-
}
|
|
431
|
-
if (!['debug', 'info', 'warn', 'error'].includes(payload.level)) {
|
|
432
|
-
throw new Error("event.log.level must be one of debug, info, warn, error in strict mode");
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
function validateStrictProgress(payload) {
|
|
436
|
-
if (!isObject(payload) || typeof payload.message !== "string" || payload.message === "") {
|
|
437
|
-
throw new Error("event.progress.message must be a non-empty string in strict mode");
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
315
|
function validateStrictError(error) {
|
|
441
316
|
if (!isObject(error))
|
|
442
317
|
throw new Error("event.error must be a JSON object in strict mode");
|
|
@@ -461,12 +336,9 @@ export class EventDecodeError extends Error {
|
|
|
461
336
|
}
|
|
462
337
|
}
|
|
463
338
|
const ERROR_RESERVED_FIELDS = new Set(["code", "message", "hint", "retryable"]);
|
|
464
|
-
const PROGRESS_RESERVED_FIELDS = new Set(["message"]);
|
|
465
|
-
const LOG_RESERVED_FIELDS = new Set(["level", "message"]);
|
|
466
339
|
/**
|
|
467
340
|
* Parse one protocol line (a single JSON text value), strict-validate it, and
|
|
468
|
-
* return a typed decoded event.
|
|
469
|
-
* the required ones, collected into `fields`.
|
|
341
|
+
* return a typed decoded event.
|
|
470
342
|
*/
|
|
471
343
|
export function decodeProtocolEvent(text) {
|
|
472
344
|
let parsed;
|
|
@@ -506,24 +378,10 @@ export function decodeProtocolEvent(text) {
|
|
|
506
378
|
decoded.hint = error.hint;
|
|
507
379
|
return decoded;
|
|
508
380
|
}
|
|
509
|
-
case "progress":
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
if (!PROGRESS_RESERVED_FIELDS.has(k))
|
|
514
|
-
fields[k] = v;
|
|
515
|
-
}
|
|
516
|
-
return { kind: "progress", message: progress.message, fields, trace };
|
|
517
|
-
}
|
|
518
|
-
case "log": {
|
|
519
|
-
const log = event.log;
|
|
520
|
-
const fields = {};
|
|
521
|
-
for (const [k, v] of Object.entries(log)) {
|
|
522
|
-
if (!LOG_RESERVED_FIELDS.has(k))
|
|
523
|
-
fields[k] = v;
|
|
524
|
-
}
|
|
525
|
-
return { kind: "log", level: log.level, message: log.message, fields, trace };
|
|
526
|
-
}
|
|
381
|
+
case "progress":
|
|
382
|
+
return { kind: "progress", progress: event.progress, trace };
|
|
383
|
+
case "log":
|
|
384
|
+
return { kind: "log", log: event.log, trace };
|
|
527
385
|
default:
|
|
528
386
|
// Unreachable: validateProtocolEvent already constrains event.kind.
|
|
529
387
|
throw new EventDecodeError(`unsupported event kind ${JSON.stringify(event.kind)}`);
|
|
@@ -603,42 +461,6 @@ export function redactUrlSecrets(url, options) {
|
|
|
603
461
|
const redacted = redactUrlInStr(url, secretNameSet(options ?? {}));
|
|
604
462
|
return redacted ?? url;
|
|
605
463
|
}
|
|
606
|
-
/**
|
|
607
|
-
* Parse a human-readable size string into bytes.
|
|
608
|
-
* Accepts numbers followed by explicit units. Decimal units are
|
|
609
|
-
* B/kB/MB/GB/TB; binary units are KiB/MiB/GiB/TiB.
|
|
610
|
-
* Trims whitespace and rejects ambiguous K/M/G/T units.
|
|
611
|
-
*/
|
|
612
|
-
export function parseSize(s) {
|
|
613
|
-
s = s.trim();
|
|
614
|
-
if (!s)
|
|
615
|
-
return null;
|
|
616
|
-
const multipliers = {
|
|
617
|
-
KiB: 1024,
|
|
618
|
-
MiB: 1024 ** 2,
|
|
619
|
-
GiB: 1024 ** 3,
|
|
620
|
-
TiB: 1024 ** 4,
|
|
621
|
-
kB: 1000,
|
|
622
|
-
MB: 1000 ** 2,
|
|
623
|
-
GB: 1000 ** 3,
|
|
624
|
-
TB: 1000 ** 4,
|
|
625
|
-
B: 1,
|
|
626
|
-
};
|
|
627
|
-
const unit = Object.keys(multipliers).find((candidate) => s.endsWith(candidate));
|
|
628
|
-
if (unit === undefined)
|
|
629
|
-
return null;
|
|
630
|
-
const numStr = s.slice(0, -unit.length);
|
|
631
|
-
const mult = multipliers[unit];
|
|
632
|
-
if (!numStr || !/^(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/.test(numStr))
|
|
633
|
-
return null;
|
|
634
|
-
const n = Number(numStr);
|
|
635
|
-
if (isNaN(n) || n < 0 || !isFinite(n))
|
|
636
|
-
return null;
|
|
637
|
-
const result = Math.trunc(n * mult);
|
|
638
|
-
if (!Number.isSafeInteger(result))
|
|
639
|
-
return null;
|
|
640
|
-
return result;
|
|
641
|
-
}
|
|
642
464
|
/**
|
|
643
465
|
* Normalize a fixed UTC offset string to "UTC" or ±HH:MM.
|
|
644
466
|
* This helper handles fixed offsets only; IANA timezone names and DST rules
|
|
@@ -686,6 +508,71 @@ export function isValidRfc3339Time(value) {
|
|
|
686
508
|
return true;
|
|
687
509
|
return value[8] === "." && value.length > 9 && /^[0-9]+$/.test(value.slice(9));
|
|
688
510
|
}
|
|
511
|
+
/**
|
|
512
|
+
* Return true when value is a complete RFC 3339 date-time, such as
|
|
513
|
+
* 2026-02-14T10:30:00Z or 2026-02-14T10:30:00.5+08:00. Composed from
|
|
514
|
+
* isValidRfc3339Date and isValidRfc3339Time: a full-date, a T/t separator, a
|
|
515
|
+
* partial-time (with optional fractional seconds), and a mandatory time-offset
|
|
516
|
+
* (Z/z or ±HH:MM with HH in 00..23 and MM in 00..59). The offset is required, so
|
|
517
|
+
* a bare 2026-02-14T10:30:00 is rejected; a space separator is rejected; and a
|
|
518
|
+
* leap second (:60) is rejected, matching isValidRfc3339Time. Non-ASCII is rejected.
|
|
519
|
+
*/
|
|
520
|
+
export function isValidRfc3339(value) {
|
|
521
|
+
if (value.length < 20 || !/^[\x00-\x7F]*$/.test(value))
|
|
522
|
+
return false;
|
|
523
|
+
if (!isValidRfc3339Date(value.slice(0, 10)))
|
|
524
|
+
return false;
|
|
525
|
+
if (value[10] !== "T" && value[10] !== "t")
|
|
526
|
+
return false;
|
|
527
|
+
const rest = value.slice(11);
|
|
528
|
+
const last = rest[rest.length - 1];
|
|
529
|
+
let partial;
|
|
530
|
+
if (last === "Z" || last === "z") {
|
|
531
|
+
partial = rest.slice(0, -1);
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
if (rest.length < 6 || !isRfc3339NumOffset(rest.slice(-6)))
|
|
535
|
+
return false;
|
|
536
|
+
partial = rest.slice(0, -6);
|
|
537
|
+
}
|
|
538
|
+
return isValidRfc3339Time(partial);
|
|
539
|
+
}
|
|
540
|
+
function isRfc3339NumOffset(offset) {
|
|
541
|
+
if (offset.length !== 6 || (offset[0] !== "+" && offset[0] !== "-") || offset[3] !== ":") {
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
const hours = parseFixedDigits(offset.slice(1, 3));
|
|
545
|
+
const minutes = parseFixedDigits(offset.slice(4, 6));
|
|
546
|
+
if (hours === null || minutes === null)
|
|
547
|
+
return false;
|
|
548
|
+
return hours <= 23 && minutes <= 59;
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Return true when value is a structurally well-formed BCP 47 (RFC 5646) language tag.
|
|
552
|
+
* A grammar-level check, not a registry lookup: hyphen-separated ASCII-alphanumeric
|
|
553
|
+
* subtags (each 1-8 chars) whose primary subtag is a 2-3 letter language code or the
|
|
554
|
+
* x/i privateuse/grandfathered lead. Rejects the POSIX underscore form (zh_CN), empty
|
|
555
|
+
* or misplaced hyphens, non-ASCII, and out-of-range primaries such as chinese. Does not
|
|
556
|
+
* verify that subtags are registered with IANA.
|
|
557
|
+
*/
|
|
558
|
+
export function isValidBcp47(value) {
|
|
559
|
+
if (!value)
|
|
560
|
+
return false;
|
|
561
|
+
const subtags = value.split("-");
|
|
562
|
+
for (let index = 0; index < subtags.length; index++) {
|
|
563
|
+
const subtag = subtags[index];
|
|
564
|
+
if (subtag.length < 1 || subtag.length > 8 || !/^[A-Za-z0-9]+$/.test(subtag)) {
|
|
565
|
+
return false;
|
|
566
|
+
}
|
|
567
|
+
if (index === 0) {
|
|
568
|
+
const isLanguage = subtag.length >= 2 && subtag.length <= 3 && /^[A-Za-z]+$/.test(subtag);
|
|
569
|
+
const isSpecial = subtag === "x" || subtag === "i";
|
|
570
|
+
if (!isLanguage && !isSpecial)
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
return true;
|
|
575
|
+
}
|
|
689
576
|
function parseUtcOffsetBody(body) {
|
|
690
577
|
if (!body)
|
|
691
578
|
return null;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Agent-First Data (AFDATA) — suffix-driven output formatting and protocol templates.
|
|
3
3
|
*/
|
|
4
|
-
export { jsonResult, jsonError, jsonProgress, jsonLog, Event, EventBuildError, JsonResultBuilder, JsonErrorBuilder, JsonProgressBuilder, JsonLogBuilder, type LogLevel, validateProtocolEvent, validateProtocolStream, decodeProtocolEvent, type DecodedEvent, type DecodedResult, type DecodedError, type DecodedProgress, type DecodedLog, EventDecodeError, type JsonValue, RedactionPolicy, OutputStyle, type OutputOptions, outputOptionsForPolicy, outputJson, outputYaml, outputPlain, redactedValue, redactUrlSecrets,
|
|
4
|
+
export { jsonResult, jsonError, jsonProgress, jsonLog, Event, EventBuildError, JsonResultBuilder, JsonErrorBuilder, JsonProgressBuilder, JsonLogBuilder, type LogLevel, validateProtocolEvent, validateProtocolStream, decodeProtocolEvent, type DecodedEvent, type DecodedResult, type DecodedError, type DecodedProgress, type DecodedLog, EventDecodeError, type JsonValue, RedactionPolicy, OutputStyle, type OutputOptions, outputOptionsForPolicy, outputJson, outputYaml, outputPlain, redactedValue, redactUrlSecrets, normalizeUtcOffset, isValidRfc3339Date, isValidRfc3339Time, isValidRfc3339, isValidBcp47, } from "./format.js";
|
|
5
5
|
export { type OutputFormat, type CliEventWriter, CliEmitter, LogFilters, cliParseOutput, cliParseLogFilters, cliOutput, buildCliError, buildCliVersion, cliRenderVersion, cliHandleVersionOrContinue, } from "./cli.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Agent-First Data (AFDATA) — suffix-driven output formatting and protocol templates.
|
|
3
3
|
*/
|
|
4
|
-
export { jsonResult, jsonError, jsonProgress, jsonLog, Event, EventBuildError, JsonResultBuilder, JsonErrorBuilder, JsonProgressBuilder, JsonLogBuilder, validateProtocolEvent, validateProtocolStream, decodeProtocolEvent, EventDecodeError, RedactionPolicy, OutputStyle, outputOptionsForPolicy, outputJson, outputYaml, outputPlain, redactedValue, redactUrlSecrets,
|
|
4
|
+
export { jsonResult, jsonError, jsonProgress, jsonLog, Event, EventBuildError, JsonResultBuilder, JsonErrorBuilder, JsonProgressBuilder, JsonLogBuilder, validateProtocolEvent, validateProtocolStream, decodeProtocolEvent, EventDecodeError, RedactionPolicy, OutputStyle, outputOptionsForPolicy, outputJson, outputYaml, outputPlain, redactedValue, redactUrlSecrets, normalizeUtcOffset, isValidRfc3339Date, isValidRfc3339Time, isValidRfc3339, isValidBcp47, } from "./format.js";
|
|
5
5
|
export { CliEmitter, LogFilters, cliParseOutput, cliParseLogFilters, cliOutput, buildCliError, buildCliVersion, cliRenderVersion, cliHandleVersionOrContinue, } from "./cli.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-first-data",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
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": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^26.1.1",
|
|
39
|
-
"tsx": "^4.23.
|
|
39
|
+
"tsx": "^4.23.1",
|
|
40
40
|
"typescript": "^7.0.2"
|
|
41
41
|
}
|
|
42
42
|
}
|