agent-first-data 0.33.0 → 0.35.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 +2 -2
- package/assets/cli-spec-v1.schema.json +4 -0
- package/dist/cli.js +12 -0
- package/dist/format.js +18 -8
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -22,11 +22,11 @@ Useful names use TypeScript casing: `render`, `outputOptionsForPolicy`, `redacte
|
|
|
22
22
|
## Behavior Notes
|
|
23
23
|
|
|
24
24
|
- Default redaction replaces every `_secret` or configured secret-name subtree with `***`, including objects and arrays.
|
|
25
|
-
- `_url` fields scrub userinfo passwords and secret-named query parameters; surrounding whitespace is trimmed and internal whitespace redacts the whole field.
|
|
25
|
+
- `_url` fields scrub userinfo passwords and secret-named query parameters; surrounding whitespace is trimmed, and internal whitespace or a `://` that is not the start of a clean URL redacts the whole field, where whitespace is the explicit Unicode `White_Space` set the spec enumerates, not the language's native predicate.
|
|
26
26
|
- `OutputOptions.redaction.urlNames` applies URL treatment to exact legacy field names
|
|
27
27
|
and recurses through collections. `redactUrlsInText` is explicit and scans
|
|
28
28
|
only complete scheme URLs, never arbitrary prose secrets.
|
|
29
|
-
- YAML keeps original keys and values (structure-preserving, like JSON), sorting keys by UTF-16 code unit order and quoting/escaping unsafe keys and string scalars. Plain strips formatting suffixes, formats values, sorts the same way, and renders nested objects/arrays as canonical JSON.
|
|
29
|
+
- YAML keeps original keys and values (structure-preserving, like JSON), sorting keys by UTF-16 code unit order and quoting/escaping unsafe keys and string scalars. Plain strips formatting suffixes, formats values, sorts the same way, and renders nested objects/arrays as canonical JSON; it quotes a value only when it contains ASCII space, tab, newline, carriage return, form feed, vertical tab, NBSP, `=`, `"`, or `\`, and escapes `\`, `"`, newline, carriage return, tab, form feed, and vertical tab inside the quotes.
|
|
30
30
|
- Logging records use `kind:"log"` with a nested `log` payload and a separate `level` field, so error-level logs are not terminal protocol errors.
|
|
31
31
|
- `buildCliError(message, hint?)` returns a strict-ready CLI error with `error.retryable:false` and `trace:{}`.
|
|
32
32
|
- Do not add a raw version/help pre-parser. Until the TypeScript `CliSpec` compiler lands, applications should keep lifecycle parsing in their own parser rather than claim AFDATA closed-world help compatibility.
|
|
@@ -100,6 +100,10 @@
|
|
|
100
100
|
"about": {
|
|
101
101
|
"$ref": "#/$defs/nonEmpty"
|
|
102
102
|
},
|
|
103
|
+
"reference_note": {
|
|
104
|
+
"description": "Prose for the generated CLI reference, rendered after this command's argument table. For the paragraph that belongs to no single argument — where a default is read from, what two options mean together — which would otherwise be hand-written into a file whose header says it is generated.",
|
|
105
|
+
"$ref": "#/$defs/nonEmpty"
|
|
106
|
+
},
|
|
103
107
|
"arguments": {
|
|
104
108
|
"type": "array",
|
|
105
109
|
"items": {
|
package/dist/cli.js
CHANGED
|
@@ -110,8 +110,19 @@ export function parseOutputTo(value) {
|
|
|
110
110
|
}
|
|
111
111
|
throw new Error("invalid --output-to: expected split, stdout, or stderr");
|
|
112
112
|
}
|
|
113
|
+
const guardedProcessStreams = new WeakSet();
|
|
114
|
+
function guardProcessStream(stream) {
|
|
115
|
+
if (guardedProcessStreams.has(stream))
|
|
116
|
+
return;
|
|
117
|
+
guardedProcessStreams.add(stream);
|
|
118
|
+
stream.on("error", (error) => {
|
|
119
|
+
if (error.code !== "EPIPE")
|
|
120
|
+
throw error;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
113
123
|
/** Event writer bound to the process stdout stream. */
|
|
114
124
|
const processStdoutWriter = (line) => {
|
|
125
|
+
guardProcessStream(process.stdout);
|
|
115
126
|
process.stdout.write(line);
|
|
116
127
|
};
|
|
117
128
|
/**
|
|
@@ -121,6 +132,7 @@ const processStdoutWriter = (line) => {
|
|
|
121
132
|
* `stderr-sink` marker is what no_stderr_policy.test.ts allows through.
|
|
122
133
|
*/
|
|
123
134
|
const processStderrWriter = (line) => {
|
|
135
|
+
guardProcessStream(process.stderr); // stderr-sink: CliEmitter diagnostic channel
|
|
124
136
|
process.stderr.write(line); // stderr-sink: CliEmitter diagnostic channel
|
|
125
137
|
};
|
|
126
138
|
/**
|
package/dist/format.js
CHANGED
|
@@ -1029,19 +1029,28 @@ function redactUrlFieldValue(s, secretNames) {
|
|
|
1029
1029
|
const redacted = redactUrlInStr(s, secretNames);
|
|
1030
1030
|
if (redacted !== null)
|
|
1031
1031
|
return redacted;
|
|
1032
|
-
|
|
1032
|
+
let start = 0;
|
|
1033
|
+
let end = s.length;
|
|
1034
|
+
while (start < end && isSpanTerminatorWhitespace(s.charCodeAt(start)))
|
|
1035
|
+
start += 1;
|
|
1036
|
+
while (end > start && isSpanTerminatorWhitespace(s.charCodeAt(end - 1)))
|
|
1037
|
+
end -= 1;
|
|
1038
|
+
const trimmed = s.slice(start, end);
|
|
1033
1039
|
if (trimmed !== s) {
|
|
1034
1040
|
const trimmedRedacted = redactUrlInStr(trimmed, secretNames);
|
|
1035
1041
|
if (trimmedRedacted !== null)
|
|
1036
1042
|
return trimmedRedacted;
|
|
1037
1043
|
}
|
|
1038
1044
|
// Fail closed: a _url value we could not parse as a clean scheme-prefixed
|
|
1039
|
-
// URL, yet which carries a credential sigil ('@' userinfo)
|
|
1040
|
-
// whitespace, is redacted wholesale rather than
|
|
1041
|
-
// connection string like user:pass@host/db
|
|
1042
|
-
// surgical span logic above,
|
|
1043
|
-
|
|
1045
|
+
// URL, yet which carries a credential sigil ('@' userinfo), internal
|
|
1046
|
+
// whitespace, or a '://' scheme separator, is redacted wholesale rather than
|
|
1047
|
+
// passed through. A schemeless connection string like user:pass@host/db
|
|
1048
|
+
// has no scheme anchor for the surgical span logic above, and a URL behind
|
|
1049
|
+
// a non-whitespace prefix (a BOM, a zero-width space, a label) has one the
|
|
1050
|
+
// span logic cannot reach, so blanket redaction is the safe default.
|
|
1051
|
+
if ([...s].some(c => isSpanTerminatorWhitespace(c.charCodeAt(0))) || s.includes("@") || s.includes("://")) {
|
|
1044
1052
|
return REDACTED_MARKER;
|
|
1053
|
+
}
|
|
1045
1054
|
return s;
|
|
1046
1055
|
}
|
|
1047
1056
|
/**
|
|
@@ -1629,7 +1638,8 @@ function isAmbiguousYamlKey(key) {
|
|
|
1629
1638
|
if (["true", "false", "null", "~", ".nan", ".inf", "+.inf", "-.inf"].includes(key.toLowerCase())) {
|
|
1630
1639
|
return true;
|
|
1631
1640
|
}
|
|
1632
|
-
return key.
|
|
1641
|
+
return ["inf", "infinity", "nan"].includes(key.replace(/^[+-]/, "").toLowerCase())
|
|
1642
|
+
|| /^[-+]?(?:[0-9]+\.?[0-9]*|\.[0-9]+)(?:[eE][-+]?[0-9]+)?$/.test(key);
|
|
1633
1643
|
}
|
|
1634
1644
|
function yamlScalar(value) {
|
|
1635
1645
|
if (typeof value === "string")
|
|
@@ -1726,7 +1736,7 @@ function plainScalarRaw(value) {
|
|
|
1726
1736
|
function quoteLogfmtValue(value) {
|
|
1727
1737
|
if (value === "")
|
|
1728
1738
|
return "";
|
|
1729
|
-
if (!/[\
|
|
1739
|
+
if (!/[ \t\n\r\f\v\u00a0="\\]/.test(value))
|
|
1730
1740
|
return value;
|
|
1731
1741
|
const escaped = value
|
|
1732
1742
|
.replace(/\\/g, "\\\\")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-first-data",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "A naming convention that lets AI agents understand your data without being told what it means, plus a CLI and library for reading Markdown structure and safely editing structured JSON, TOML, YAML, dotenv, and INI documents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"test": "tsx --test src/*.test.ts"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@types/node": "^26.
|
|
31
|
-
"tsx": "^4.23.
|
|
30
|
+
"@types/node": "^26.6.4",
|
|
31
|
+
"tsx": "^4.23.15",
|
|
32
32
|
"typescript": "^7.0.2"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|