/** * What a conversation, a log line, and a printed config must not publish * verbatim. One capability with two ways in, because a caller has one of two * things: text, or structure. * * `redactText` is for text — a command line, an assistant message, a serialized * payload — and finds secrets by shape. `isSecretKeyName` is for structure, * where a field's *name* already says the value is a secret and no shape * matching is needed or wanted. They share one list of secret key names, which * is why this module exists: that list used to be written out three times, and * the three copies had drifted. */ /** * A value shaped like JSON, declared here rather than imported. * * JSON is not a Dreamux concept, and this package deliberately knows no Dreamux * contracts: `@excitedjs/dreamux-types` is the type set an *external provider* * compiles against, so a utility every layer calls must not reach into it — not * even for a type. The shape is structural, so a caller holding that package's * `JsonValue` passes one of these without a cast. */ export type JsonValue = null | boolean | number | string | readonly JsonValue[] | { readonly [key: string]: JsonValue; }; /** * Redaction never truncates. How much of a payload a surface can show is that * surface's own limit, applied where it sends. Cutting here would hand every * surface an already-damaged value — a JSON result that no longer parses — * with no way to get it back. */ export interface RedactedText { value: string; redacted: boolean; } /** * Whether a field's *name* says its value is a secret. * * Structure needs no shape matching: a caller holding `{ api_key: "..." }` * knows the value is a secret whatever it looks like, and a low-entropy or * oddly-punctuated one would slip past every pattern. The substring test is * deliberate, so `feishu_app_secret` and `refreshToken` both count. */ export declare function isSecretKeyName(key: string): boolean; /** * Replace, in place, every value whose key names a secret — at any depth. * * The caller owns a parsed, mutable structure it is about to display, and this * is the one thing it must not show. Values are destroyed rather than masked * by shape, because the key already settled the question. `replacement` * defaults to the display placeholder every existing caller wants; a caller * that instead needs an empty-string projection (a config surface that hands * the value back out for editing, where `''` would look like a real * value) passes `''`. */ export declare function redactSecretKeyValues(value: unknown, replacement?: unknown): void; /** * Rewrite what displayed text must not publish verbatim. * * Two different jobs share this function. Secrets are *destroyed* — a token has * no legible form worth keeping. Paths are only *renamed*: a reader still needs * to know which file was touched, so the workspace becomes `.` and this host's * home becomes `~`, exactly the way the operator's own shell prints them. Order * matters: the workspace usually sits under the home, so relativizing it first * keeps the shorter, more useful form. * * `homePaths` is explicit so this stays pure and never depends on * process-global resolution state. */ export declare function redactText(value: string, cwd: string, homePaths: readonly string[]): RedactedText; /** * Redact a JSON value by walking it, not by reading its serialization. * * Text is the wrong level for a payload that has structure. Serializing first * hides every string inside escapes — `{"client_secret":"x"}` written into a * field becomes `{\"client_secret\":\"x\"}`, where the key no longer sits * beside its separator and no pattern tuned for text can see it, at any nesting * depth. Walking removes the problem instead of chasing it: each level of * structure is peeled by the caller that parsed it, so every string this * reaches is ordinary text, which is the one thing `redactText` is good at. * * Two rules, and a key outranks a shape. A field whose *name* says secret has * its value destroyed whatever it looks like, which is what catches the * low-entropy and oddly-punctuated values no pattern would. Every other string * goes through `redactText`. Numbers and booleans carry neither a secret worth * masking nor a path worth renaming, so they travel as they are. * * The result is a new value; the input is not touched. Because the structure * survives, a caller that serializes afterwards always gets valid JSON. */ export declare function redactJson(value: JsonValue | null, cwd: string, homePaths: readonly string[]): { value: JsonValue | null; redacted: boolean; }; //# sourceMappingURL=redaction.d.ts.map