@stll/anonymize 2.4.2 → 2.5.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.
@@ -0,0 +1,91 @@
1
+ //#region src/agent-surface.d.ts
2
+ /**
3
+ * The agent-facing surface contract shared by the CLI (`@stll/anonymize-cli`)
4
+ * and the MCP server (`@stll/anonymize-mcp`).
5
+ *
6
+ * Both surfaces are driven mostly by AI agents. To stay legible to them, every
7
+ * tool/command failure carries one of a closed set of machine-readable `code`s
8
+ * alongside a human `message` and an actionable `hint`; the MCP server returns
9
+ * the `{ error: { code, message, hint, retryable } }` envelope with `isError`,
10
+ * and the CLI maps the same `code` to a distinct process exit code. The two
11
+ * surfaces do not talk to each other (the CLI drives the WASM engine directly),
12
+ * so they share the taxonomy through this runtime-free module rather than a
13
+ * call path.
14
+ *
15
+ * The set is closed: a new failure mode must reuse a code here or add one
16
+ * deliberately (and pick a fresh exit code). This module must stay runtime-free
17
+ * (no wasm, no node built-ins) so any consumer can import it cheaply.
18
+ */
19
+ declare const ANONYMIZE_ERROR_CODES: readonly ["validation_error", "path_not_allowed", "not_found", "unsupported_format", "output_exists", "session_unavailable", "dependency_missing", "internal_error"];
20
+ type AnonymizeErrorCode = (typeof ANONYMIZE_ERROR_CODES)[number];
21
+ /**
22
+ * The structured tool-error envelope the MCP surface returns (alongside
23
+ * `isError: true`). `hint` states the next step for the agent; `retryable`
24
+ * says whether retrying the same call unchanged could plausibly succeed.
25
+ */
26
+ type AnonymizeErrorEnvelope = {
27
+ error: {
28
+ code: AnonymizeErrorCode;
29
+ message: string;
30
+ hint: string;
31
+ retryable: boolean;
32
+ };
33
+ };
34
+ /**
35
+ * Process exit codes for the CLI. `ok`/`unexpected`/`usage` are the pre-existing
36
+ * classes (0/1/2); the remaining classes are keyed off the error codes above so
37
+ * an agent can branch on the exit code without parsing stderr. Every error code
38
+ * maps to a distinct exit code (asserted in `agent-surface.test.ts`).
39
+ */
40
+ declare const EXIT_CODES: {
41
+ readonly ok: 0;
42
+ readonly unexpected: 1;
43
+ readonly usage: 2;
44
+ readonly pathNotAllowed: 3;
45
+ readonly notFound: 4;
46
+ readonly unsupportedFormat: 5;
47
+ readonly outputExists: 6;
48
+ readonly sessionUnavailable: 7;
49
+ readonly dependencyMissing: 8;
50
+ };
51
+ type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];
52
+ /**
53
+ * Map every error code to its CLI exit class. `validation_error` shares the
54
+ * `usage` class (2) with the CLI's own `UsageError`: both mean "the invocation
55
+ * was malformed, fix the input". `internal_error` maps to the generic
56
+ * `unexpected` class (1).
57
+ */
58
+ declare const ERROR_CODE_EXIT_MAP: Readonly<Record<AnonymizeErrorCode, ExitCode>>;
59
+ type SurfaceErrorOptions = {
60
+ hint: string;
61
+ retryable?: boolean;
62
+ cause?: unknown;
63
+ };
64
+ /**
65
+ * A failure carrying a stable agent-surface `code`, a `hint`, and a `retryable`
66
+ * flag. Service and engine code throws this instead of a plain `Error` so both
67
+ * surfaces can classify it: the MCP boundary renders it as the error envelope,
68
+ * the CLI maps it to an exit code. Messages must stay content-free (never echo
69
+ * raw input text or detected entities).
70
+ */
71
+ declare class AnonymizeSurfaceError extends Error {
72
+ readonly code: AnonymizeErrorCode;
73
+ readonly hint: string;
74
+ readonly retryable: boolean;
75
+ constructor(code: AnonymizeErrorCode, message: string, { hint, retryable, cause }: SurfaceErrorOptions);
76
+ }
77
+ declare const isAnonymizeSurfaceError: (value: unknown) => value is AnonymizeSurfaceError;
78
+ /** Build the wire error envelope from a surface error. */
79
+ declare const toErrorEnvelope: (error: AnonymizeSurfaceError) => AnonymizeErrorEnvelope;
80
+ /**
81
+ * Classify an arbitrary thrown value into the error envelope. A
82
+ * `AnonymizeSurfaceError` keeps its code; anything else collapses to
83
+ * `internal_error` with its detail withheld, so unexpected failures never leak
84
+ * raw text or stack detail to the caller.
85
+ */
86
+ declare const classifyToEnvelope: (error: unknown) => AnonymizeErrorEnvelope;
87
+ /** The CLI exit code for a thrown value (non-surface errors are `unexpected`). */
88
+ declare const exitCodeForError: (error: unknown) => ExitCode;
89
+ //#endregion
90
+ export { ANONYMIZE_ERROR_CODES, AnonymizeErrorCode, AnonymizeErrorEnvelope, AnonymizeSurfaceError, ERROR_CODE_EXIT_MAP, EXIT_CODES, ExitCode, classifyToEnvelope, exitCodeForError, isAnonymizeSurfaceError, toErrorEnvelope };
91
+ //# sourceMappingURL=agent-surface.d.mts.map
@@ -0,0 +1,109 @@
1
+ //#region src/agent-surface.ts
2
+ /**
3
+ * The agent-facing surface contract shared by the CLI (`@stll/anonymize-cli`)
4
+ * and the MCP server (`@stll/anonymize-mcp`).
5
+ *
6
+ * Both surfaces are driven mostly by AI agents. To stay legible to them, every
7
+ * tool/command failure carries one of a closed set of machine-readable `code`s
8
+ * alongside a human `message` and an actionable `hint`; the MCP server returns
9
+ * the `{ error: { code, message, hint, retryable } }` envelope with `isError`,
10
+ * and the CLI maps the same `code` to a distinct process exit code. The two
11
+ * surfaces do not talk to each other (the CLI drives the WASM engine directly),
12
+ * so they share the taxonomy through this runtime-free module rather than a
13
+ * call path.
14
+ *
15
+ * The set is closed: a new failure mode must reuse a code here or add one
16
+ * deliberately (and pick a fresh exit code). This module must stay runtime-free
17
+ * (no wasm, no node built-ins) so any consumer can import it cheaply.
18
+ */
19
+ const ANONYMIZE_ERROR_CODES = [
20
+ "validation_error",
21
+ "path_not_allowed",
22
+ "not_found",
23
+ "unsupported_format",
24
+ "output_exists",
25
+ "session_unavailable",
26
+ "dependency_missing",
27
+ "internal_error"
28
+ ];
29
+ /**
30
+ * Process exit codes for the CLI. `ok`/`unexpected`/`usage` are the pre-existing
31
+ * classes (0/1/2); the remaining classes are keyed off the error codes above so
32
+ * an agent can branch on the exit code without parsing stderr. Every error code
33
+ * maps to a distinct exit code (asserted in `agent-surface.test.ts`).
34
+ */
35
+ const EXIT_CODES = {
36
+ ok: 0,
37
+ unexpected: 1,
38
+ usage: 2,
39
+ pathNotAllowed: 3,
40
+ notFound: 4,
41
+ unsupportedFormat: 5,
42
+ outputExists: 6,
43
+ sessionUnavailable: 7,
44
+ dependencyMissing: 8
45
+ };
46
+ /**
47
+ * Map every error code to its CLI exit class. `validation_error` shares the
48
+ * `usage` class (2) with the CLI's own `UsageError`: both mean "the invocation
49
+ * was malformed, fix the input". `internal_error` maps to the generic
50
+ * `unexpected` class (1).
51
+ */
52
+ const ERROR_CODE_EXIT_MAP = {
53
+ validation_error: EXIT_CODES.usage,
54
+ path_not_allowed: EXIT_CODES.pathNotAllowed,
55
+ not_found: EXIT_CODES.notFound,
56
+ unsupported_format: EXIT_CODES.unsupportedFormat,
57
+ output_exists: EXIT_CODES.outputExists,
58
+ session_unavailable: EXIT_CODES.sessionUnavailable,
59
+ dependency_missing: EXIT_CODES.dependencyMissing,
60
+ internal_error: EXIT_CODES.unexpected
61
+ };
62
+ /**
63
+ * A failure carrying a stable agent-surface `code`, a `hint`, and a `retryable`
64
+ * flag. Service and engine code throws this instead of a plain `Error` so both
65
+ * surfaces can classify it: the MCP boundary renders it as the error envelope,
66
+ * the CLI maps it to an exit code. Messages must stay content-free (never echo
67
+ * raw input text or detected entities).
68
+ */
69
+ var AnonymizeSurfaceError = class extends Error {
70
+ code;
71
+ hint;
72
+ retryable;
73
+ constructor(code, message, { hint, retryable = false, cause }) {
74
+ super(message, cause === void 0 ? void 0 : { cause });
75
+ this.name = "AnonymizeSurfaceError";
76
+ this.code = code;
77
+ this.hint = hint;
78
+ this.retryable = retryable;
79
+ }
80
+ };
81
+ const isAnonymizeSurfaceError = (value) => value instanceof AnonymizeSurfaceError;
82
+ /** Build the wire error envelope from a surface error. */
83
+ const toErrorEnvelope = (error) => ({ error: {
84
+ code: error.code,
85
+ message: error.message,
86
+ hint: error.hint,
87
+ retryable: error.retryable
88
+ } });
89
+ /**
90
+ * Classify an arbitrary thrown value into the error envelope. A
91
+ * `AnonymizeSurfaceError` keeps its code; anything else collapses to
92
+ * `internal_error` with its detail withheld, so unexpected failures never leak
93
+ * raw text or stack detail to the caller.
94
+ */
95
+ const classifyToEnvelope = (error) => {
96
+ if (isAnonymizeSurfaceError(error)) return toErrorEnvelope(error);
97
+ return { error: {
98
+ code: "internal_error",
99
+ message: "The operation failed unexpectedly.",
100
+ hint: "Retry; if it persists, file it with the send_feedback tool.",
101
+ retryable: true
102
+ } };
103
+ };
104
+ /** The CLI exit code for a thrown value (non-surface errors are `unexpected`). */
105
+ const exitCodeForError = (error) => isAnonymizeSurfaceError(error) ? ERROR_CODE_EXIT_MAP[error.code] : EXIT_CODES.unexpected;
106
+ //#endregion
107
+ export { ANONYMIZE_ERROR_CODES, AnonymizeSurfaceError, ERROR_CODE_EXIT_MAP, EXIT_CODES, classifyToEnvelope, exitCodeForError, isAnonymizeSurfaceError, toErrorEnvelope };
108
+
109
+ //# sourceMappingURL=agent-surface.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-surface.mjs","names":[],"sources":["../src/agent-surface.ts"],"sourcesContent":["/**\n * The agent-facing surface contract shared by the CLI (`@stll/anonymize-cli`)\n * and the MCP server (`@stll/anonymize-mcp`).\n *\n * Both surfaces are driven mostly by AI agents. To stay legible to them, every\n * tool/command failure carries one of a closed set of machine-readable `code`s\n * alongside a human `message` and an actionable `hint`; the MCP server returns\n * the `{ error: { code, message, hint, retryable } }` envelope with `isError`,\n * and the CLI maps the same `code` to a distinct process exit code. The two\n * surfaces do not talk to each other (the CLI drives the WASM engine directly),\n * so they share the taxonomy through this runtime-free module rather than a\n * call path.\n *\n * The set is closed: a new failure mode must reuse a code here or add one\n * deliberately (and pick a fresh exit code). This module must stay runtime-free\n * (no wasm, no node built-ins) so any consumer can import it cheaply.\n */\n\nexport const ANONYMIZE_ERROR_CODES = [\n /** Input failed validation at the boundary (shape, type, size, arguments). */\n \"validation_error\",\n /** A path resolved outside the configured roots, or was not absolute. */\n \"path_not_allowed\",\n /** The named input path or session key does not exist. */\n \"not_found\",\n /** The input's extension or content is not a supported document type. */\n \"unsupported_format\",\n /** The output path already exists; anonymize never overwrites. */\n \"output_exists\",\n /** A restore needs a durable session store that is not configured. */\n \"session_unavailable\",\n /** An external tool (pdftoppm, tesseract) was missing or not executable. */\n \"dependency_missing\",\n /** An unexpected internal failure; detail is not leaked to the caller. */\n \"internal_error\",\n] as const;\n\nexport type AnonymizeErrorCode = (typeof ANONYMIZE_ERROR_CODES)[number];\n\n/**\n * The structured tool-error envelope the MCP surface returns (alongside\n * `isError: true`). `hint` states the next step for the agent; `retryable`\n * says whether retrying the same call unchanged could plausibly succeed.\n */\nexport type AnonymizeErrorEnvelope = {\n error: {\n code: AnonymizeErrorCode;\n message: string;\n hint: string;\n retryable: boolean;\n };\n};\n\n/**\n * Process exit codes for the CLI. `ok`/`unexpected`/`usage` are the pre-existing\n * classes (0/1/2); the remaining classes are keyed off the error codes above so\n * an agent can branch on the exit code without parsing stderr. Every error code\n * maps to a distinct exit code (asserted in `agent-surface.test.ts`).\n */\nexport const EXIT_CODES = {\n ok: 0,\n unexpected: 1,\n usage: 2,\n pathNotAllowed: 3,\n notFound: 4,\n unsupportedFormat: 5,\n outputExists: 6,\n sessionUnavailable: 7,\n dependencyMissing: 8,\n} as const;\n\nexport type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];\n\n/**\n * Map every error code to its CLI exit class. `validation_error` shares the\n * `usage` class (2) with the CLI's own `UsageError`: both mean \"the invocation\n * was malformed, fix the input\". `internal_error` maps to the generic\n * `unexpected` class (1).\n */\nexport const ERROR_CODE_EXIT_MAP: Readonly<\n Record<AnonymizeErrorCode, ExitCode>\n> = {\n validation_error: EXIT_CODES.usage,\n path_not_allowed: EXIT_CODES.pathNotAllowed,\n not_found: EXIT_CODES.notFound,\n unsupported_format: EXIT_CODES.unsupportedFormat,\n output_exists: EXIT_CODES.outputExists,\n session_unavailable: EXIT_CODES.sessionUnavailable,\n dependency_missing: EXIT_CODES.dependencyMissing,\n internal_error: EXIT_CODES.unexpected,\n};\n\ntype SurfaceErrorOptions = {\n hint: string;\n retryable?: boolean;\n cause?: unknown;\n};\n\n/**\n * A failure carrying a stable agent-surface `code`, a `hint`, and a `retryable`\n * flag. Service and engine code throws this instead of a plain `Error` so both\n * surfaces can classify it: the MCP boundary renders it as the error envelope,\n * the CLI maps it to an exit code. Messages must stay content-free (never echo\n * raw input text or detected entities).\n */\nexport class AnonymizeSurfaceError extends Error {\n readonly code: AnonymizeErrorCode;\n readonly hint: string;\n readonly retryable: boolean;\n\n constructor(\n code: AnonymizeErrorCode,\n message: string,\n { hint, retryable = false, cause }: SurfaceErrorOptions,\n ) {\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"AnonymizeSurfaceError\";\n this.code = code;\n this.hint = hint;\n this.retryable = retryable;\n }\n}\n\nexport const isAnonymizeSurfaceError = (\n value: unknown,\n): value is AnonymizeSurfaceError => value instanceof AnonymizeSurfaceError;\n\n/** Build the wire error envelope from a surface error. */\nexport const toErrorEnvelope = (\n error: AnonymizeSurfaceError,\n): AnonymizeErrorEnvelope => ({\n error: {\n code: error.code,\n message: error.message,\n hint: error.hint,\n retryable: error.retryable,\n },\n});\n\n/**\n * Classify an arbitrary thrown value into the error envelope. A\n * `AnonymizeSurfaceError` keeps its code; anything else collapses to\n * `internal_error` with its detail withheld, so unexpected failures never leak\n * raw text or stack detail to the caller.\n */\nexport const classifyToEnvelope = (error: unknown): AnonymizeErrorEnvelope => {\n if (isAnonymizeSurfaceError(error)) {\n return toErrorEnvelope(error);\n }\n return {\n error: {\n code: \"internal_error\",\n message: \"The operation failed unexpectedly.\",\n hint: \"Retry; if it persists, file it with the send_feedback tool.\",\n retryable: true,\n },\n };\n};\n\n/** The CLI exit code for a thrown value (non-surface errors are `unexpected`). */\nexport const exitCodeForError = (error: unknown): ExitCode =>\n isAnonymizeSurfaceError(error)\n ? ERROR_CODE_EXIT_MAP[error.code]\n : EXIT_CODES.unexpected;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,MAAa,wBAAwB;CAEnC;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;AACF;;;;;;;AAwBA,MAAa,aAAa;CACxB,IAAI;CACJ,YAAY;CACZ,OAAO;CACP,gBAAgB;CAChB,UAAU;CACV,mBAAmB;CACnB,cAAc;CACd,oBAAoB;CACpB,mBAAmB;AACrB;;;;;;;AAUA,MAAa,sBAET;CACF,kBAAkB,WAAW;CAC7B,kBAAkB,WAAW;CAC7B,WAAW,WAAW;CACtB,oBAAoB,WAAW;CAC/B,eAAe,WAAW;CAC1B,qBAAqB,WAAW;CAChC,oBAAoB,WAAW;CAC/B,gBAAgB,WAAW;AAC7B;;;;;;;;AAeA,IAAa,wBAAb,cAA2C,MAAM;CAC/C;CACA;CACA;CAEA,YACE,MACA,SACA,EAAE,MAAM,YAAY,OAAO,SAC3B;EACA,MAAM,SAAS,UAAU,KAAA,IAAY,KAAA,IAAY,EAAE,MAAM,CAAC;EAC1D,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,KAAK,YAAY;CACnB;AACF;AAEA,MAAa,2BACX,UACmC,iBAAiB;;AAGtD,MAAa,mBACX,WAC4B,EAC5B,OAAO;CACL,MAAM,MAAM;CACZ,SAAS,MAAM;CACf,MAAM,MAAM;CACZ,WAAW,MAAM;AACnB,EACF;;;;;;;AAQA,MAAa,sBAAsB,UAA2C;CAC5E,IAAI,wBAAwB,KAAK,GAC/B,OAAO,gBAAgB,KAAK;CAE9B,OAAO,EACL,OAAO;EACL,MAAM;EACN,SAAS;EACT,MAAM;EACN,WAAW;CACb,EACF;AACF;;AAGA,MAAa,oBAAoB,UAC/B,wBAAwB,KAAK,IACzB,oBAAoB,MAAM,QAC1B,WAAW"}
@@ -0,0 +1,32 @@
1
+ //#region src/feedback-sanitize.d.ts
2
+ /**
3
+ * Deterministic, regex-based redaction for agent-authored feedback text.
4
+ *
5
+ * Both agent surfaces (`@stll/anonymize-cli`, `@stll/anonymize-mcp`) can file a
6
+ * bug or gap via feedback. The free-text title/body can accidentally carry a
7
+ * client email, an id, an auth token, or an internal URL. This module strips the
8
+ * obvious shapes before the text is ever shown to a human or placed into a
9
+ * prefilled GitHub issue URL. It is a coarse safety net, not a guarantee: the
10
+ * real control is human approval (nothing is published until the human opens and
11
+ * submits the prefilled issue) and the fact that this surface never sends over
12
+ * the network. The heavy WASM anonymization pipeline is deliberately not run
13
+ * here: feedback is short free text, and regex plus human approval is the
14
+ * accepted baseline (it also keeps this module runtime-free).
15
+ *
16
+ * Pass order is load-bearing: JWT/secret shapes run before URL so a secret in a
17
+ * query string of a preserved public URL is still redacted while the URL is kept.
18
+ */
19
+ type SanitizeFeedbackResult = {
20
+ text: string;
21
+ redactions: number;
22
+ };
23
+ /**
24
+ * Redact the well-known sensitive shapes from one feedback field. Returns the
25
+ * cleaned text and the number of substitutions made (surfaced to the human so
26
+ * they can judge how much was stripped). Each pass replaces with a bracketed
27
+ * placeholder, so a downstream pass never re-matches an earlier placeholder.
28
+ */
29
+ declare const sanitizeFeedbackText: (input: string) => SanitizeFeedbackResult;
30
+ //#endregion
31
+ export { SanitizeFeedbackResult, sanitizeFeedbackText };
32
+ //# sourceMappingURL=feedback-sanitize.d.mts.map
@@ -0,0 +1,143 @@
1
+ //#region src/feedback-sanitize.ts
2
+ /**
3
+ * Deterministic, regex-based redaction for agent-authored feedback text.
4
+ *
5
+ * Both agent surfaces (`@stll/anonymize-cli`, `@stll/anonymize-mcp`) can file a
6
+ * bug or gap via feedback. The free-text title/body can accidentally carry a
7
+ * client email, an id, an auth token, or an internal URL. This module strips the
8
+ * obvious shapes before the text is ever shown to a human or placed into a
9
+ * prefilled GitHub issue URL. It is a coarse safety net, not a guarantee: the
10
+ * real control is human approval (nothing is published until the human opens and
11
+ * submits the prefilled issue) and the fact that this surface never sends over
12
+ * the network. The heavy WASM anonymization pipeline is deliberately not run
13
+ * here: feedback is short free text, and regex plus human approval is the
14
+ * accepted baseline (it also keeps this module runtime-free).
15
+ *
16
+ * Pass order is load-bearing: JWT/secret shapes run before URL so a secret in a
17
+ * query string of a preserved public URL is still redacted while the URL is kept.
18
+ */
19
+ const REDACTED_EMAIL = "[redacted-email]";
20
+ const REDACTED_ID = "[redacted-id]";
21
+ const REDACTED_SECRET = "[redacted-secret]";
22
+ const REDACTED_URL = "[redacted-url]";
23
+ const REDACTED_IP = "[redacted-ip]";
24
+ const hasNoPrivateUrlParts = (url) => url.username === "" && url.password === "" && url.search === "" && url.hash === "";
25
+ /**
26
+ * The only URL preserved verbatim is the project's own public GitHub repo, so a
27
+ * feedback body can reference an existing issue or file without being redacted.
28
+ * Everything else (including other hosts) is stripped.
29
+ */
30
+ const isPreservedPublicUrl = (url) => {
31
+ if (!hasNoPrivateUrlParts(url)) return false;
32
+ if (url.hostname.toLowerCase() !== "github.com") return false;
33
+ return url.pathname === "/stella/anonymize" || url.pathname.startsWith("/stella/anonymize/");
34
+ };
35
+ const JWT_REGEX = /\b[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/gu;
36
+ const HEX_SECRET_REGEX = /\b[0-9a-fA-F]{32,}\b/gu;
37
+ const BASE64_SECRET_REGEX = /\b[A-Za-z0-9_-]{40,}={0,2}/gu;
38
+ const URL_REGEX = /\bhttps?:\/\/[^\s<>"'`]+/giu;
39
+ const URL_TRAILING_PUNCTUATION_REGEX = /[.,;:!?]+$/u;
40
+ const EMAIL_REGEX = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/gu;
41
+ const UUID_REGEX = /\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b/gu;
42
+ const IPV4_REGEX = /\b\d{1,3}(?:\.\d{1,3}){3}\b/gu;
43
+ const IPV6_REGEX = /\b(?:[0-9a-fA-F]{1,4}:){2,7}[0-9a-fA-F]{1,4}\b|\b(?:[0-9a-fA-F]{1,4}:){1,6}:(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}\b/gu;
44
+ const trimTrailingUrlPunctuation = (match) => {
45
+ let core = match;
46
+ let trailing = "";
47
+ const sentencePunctuation = URL_TRAILING_PUNCTUATION_REGEX.exec(core)?.[0] ?? "";
48
+ if (sentencePunctuation.length > 0) {
49
+ core = core.slice(0, -sentencePunctuation.length);
50
+ trailing = sentencePunctuation;
51
+ }
52
+ const pairs = [
53
+ {
54
+ open: "(",
55
+ close: ")"
56
+ },
57
+ {
58
+ open: "[",
59
+ close: "]"
60
+ },
61
+ {
62
+ open: "{",
63
+ close: "}"
64
+ }
65
+ ];
66
+ let changed = true;
67
+ while (changed) {
68
+ changed = false;
69
+ for (const { close, open } of pairs) {
70
+ if (!core.endsWith(close)) continue;
71
+ const opens = Array.from(core).filter((char) => char === open).length;
72
+ if (Array.from(core).filter((char) => char === close).length <= opens) continue;
73
+ core = core.slice(0, -close.length);
74
+ trailing = `${close}${trailing}`;
75
+ changed = true;
76
+ }
77
+ }
78
+ return {
79
+ core,
80
+ trailing
81
+ };
82
+ };
83
+ /**
84
+ * Redact the well-known sensitive shapes from one feedback field. Returns the
85
+ * cleaned text and the number of substitutions made (surfaced to the human so
86
+ * they can judge how much was stripped). Each pass replaces with a bracketed
87
+ * placeholder, so a downstream pass never re-matches an earlier placeholder.
88
+ */
89
+ const sanitizeFeedbackText = (input) => {
90
+ let redactions = 0;
91
+ const bump = () => {
92
+ redactions += 1;
93
+ };
94
+ let text = input;
95
+ text = text.replace(JWT_REGEX, () => {
96
+ bump();
97
+ return REDACTED_SECRET;
98
+ });
99
+ text = text.replace(HEX_SECRET_REGEX, () => {
100
+ bump();
101
+ return REDACTED_SECRET;
102
+ });
103
+ text = text.replace(BASE64_SECRET_REGEX, () => {
104
+ bump();
105
+ return REDACTED_SECRET;
106
+ });
107
+ text = text.replace(URL_REGEX, (match) => {
108
+ const { core, trailing } = trimTrailingUrlPunctuation(match);
109
+ let url;
110
+ try {
111
+ url = new URL(core);
112
+ } catch {
113
+ return match;
114
+ }
115
+ if (isPreservedPublicUrl(url)) return match;
116
+ bump();
117
+ return `${REDACTED_URL}${trailing}`;
118
+ });
119
+ text = text.replace(EMAIL_REGEX, () => {
120
+ bump();
121
+ return REDACTED_EMAIL;
122
+ });
123
+ text = text.replace(UUID_REGEX, () => {
124
+ bump();
125
+ return REDACTED_ID;
126
+ });
127
+ text = text.replace(IPV4_REGEX, () => {
128
+ bump();
129
+ return REDACTED_IP;
130
+ });
131
+ text = text.replace(IPV6_REGEX, () => {
132
+ bump();
133
+ return REDACTED_IP;
134
+ });
135
+ return {
136
+ text,
137
+ redactions
138
+ };
139
+ };
140
+ //#endregion
141
+ export { sanitizeFeedbackText };
142
+
143
+ //# sourceMappingURL=feedback-sanitize.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-sanitize.mjs","names":[],"sources":["../src/feedback-sanitize.ts"],"sourcesContent":["/**\n * Deterministic, regex-based redaction for agent-authored feedback text.\n *\n * Both agent surfaces (`@stll/anonymize-cli`, `@stll/anonymize-mcp`) can file a\n * bug or gap via feedback. The free-text title/body can accidentally carry a\n * client email, an id, an auth token, or an internal URL. This module strips the\n * obvious shapes before the text is ever shown to a human or placed into a\n * prefilled GitHub issue URL. It is a coarse safety net, not a guarantee: the\n * real control is human approval (nothing is published until the human opens and\n * submits the prefilled issue) and the fact that this surface never sends over\n * the network. The heavy WASM anonymization pipeline is deliberately not run\n * here: feedback is short free text, and regex plus human approval is the\n * accepted baseline (it also keeps this module runtime-free).\n *\n * Pass order is load-bearing: JWT/secret shapes run before URL so a secret in a\n * query string of a preserved public URL is still redacted while the URL is kept.\n */\n\nconst REDACTED_EMAIL = \"[redacted-email]\";\nconst REDACTED_ID = \"[redacted-id]\";\nconst REDACTED_SECRET = \"[redacted-secret]\";\nconst REDACTED_URL = \"[redacted-url]\";\nconst REDACTED_IP = \"[redacted-ip]\";\n\nconst hasNoPrivateUrlParts = (url: URL): boolean =>\n url.username === \"\" &&\n url.password === \"\" &&\n url.search === \"\" &&\n url.hash === \"\";\n\n/**\n * The only URL preserved verbatim is the project's own public GitHub repo, so a\n * feedback body can reference an existing issue or file without being redacted.\n * Everything else (including other hosts) is stripped.\n */\nconst isPreservedPublicUrl = (url: URL): boolean => {\n if (!hasNoPrivateUrlParts(url)) {\n return false;\n }\n if (url.hostname.toLowerCase() !== \"github.com\") {\n return false;\n }\n return (\n url.pathname === \"/stella/anonymize\" ||\n url.pathname.startsWith(\"/stella/anonymize/\")\n );\n};\n\n// Three dot-separated base64url segments, each long enough to be a real token\n// (>= 10 chars), so version strings (\"1.2.3\") and IPv4 literals never match.\nconst JWT_REGEX =\n /\\b[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}\\b/gu;\n\n// Long hex blob (>= 32 chars): API keys, hashes, un-hyphenated ids.\nconst HEX_SECRET_REGEX = /\\b[0-9a-fA-F]{32,}\\b/gu;\n\n// Long base64url blob (>= 40 chars): opaque access tokens, secrets. The\n// base64url alphabet (no `+` or `/`) is used on purpose: including `/` would let\n// this pass swallow whole URL path segments, and modern tokens (GitHub PATs, JWT\n// parts, most API keys) are base64url anyway. A hex secret is caught by\n// HEX_SECRET_REGEX above.\nconst BASE64_SECRET_REGEX = /\\b[A-Za-z0-9_-]{40,}={0,2}/gu;\n\n// Absolute http(s) URL. Parentheses/brackets are valid path characters and are\n// intentionally included; unmatched closing wrappers and sentence punctuation\n// are trimmed in the replacer.\nconst URL_REGEX = /\\bhttps?:\\/\\/[^\\s<>\"'`]+/giu;\nconst URL_TRAILING_PUNCTUATION_REGEX = /[.,;:!?]+$/u;\n\nconst EMAIL_REGEX = /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b/gu;\n\nconst UUID_REGEX =\n /\\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\\b/gu;\n\nconst IPV4_REGEX = /\\b\\d{1,3}(?:\\.\\d{1,3}){3}\\b/gu;\n\n// Full-form and mid/tail-compressed IPv6. Fully leading-compressed forms\n// (\"::1\") are intentionally out of scope: requiring at least one leading hex\n// group keeps code tokens like `std::vector` from being misread as an address.\nconst IPV6_REGEX =\n /\\b(?:[0-9a-fA-F]{1,4}:){2,7}[0-9a-fA-F]{1,4}\\b|\\b(?:[0-9a-fA-F]{1,4}:){1,6}:(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}\\b/gu;\n\nexport type SanitizeFeedbackResult = { text: string; redactions: number };\n\nconst trimTrailingUrlPunctuation = (\n match: string,\n): { core: string; trailing: string } => {\n let core = match;\n let trailing = \"\";\n\n const sentencePunctuation =\n URL_TRAILING_PUNCTUATION_REGEX.exec(core)?.[0] ?? \"\";\n if (sentencePunctuation.length > 0) {\n core = core.slice(0, -sentencePunctuation.length);\n trailing = sentencePunctuation;\n }\n\n const pairs = [\n { open: \"(\", close: \")\" },\n { open: \"[\", close: \"]\" },\n { open: \"{\", close: \"}\" },\n ] as const;\n let changed = true;\n while (changed) {\n changed = false;\n for (const { close, open } of pairs) {\n if (!core.endsWith(close)) {\n continue;\n }\n const opens = Array.from(core).filter((char) => char === open).length;\n const closes = Array.from(core).filter((char) => char === close).length;\n if (closes <= opens) {\n continue;\n }\n core = core.slice(0, -close.length);\n trailing = `${close}${trailing}`;\n changed = true;\n }\n }\n\n return { core, trailing };\n};\n\n/**\n * Redact the well-known sensitive shapes from one feedback field. Returns the\n * cleaned text and the number of substitutions made (surfaced to the human so\n * they can judge how much was stripped). Each pass replaces with a bracketed\n * placeholder, so a downstream pass never re-matches an earlier placeholder.\n */\nexport const sanitizeFeedbackText = (input: string): SanitizeFeedbackResult => {\n let redactions = 0;\n const bump = (): void => {\n redactions += 1;\n };\n\n let text = input;\n\n text = text.replace(JWT_REGEX, () => {\n bump();\n return REDACTED_SECRET;\n });\n text = text.replace(HEX_SECRET_REGEX, () => {\n bump();\n return REDACTED_SECRET;\n });\n text = text.replace(BASE64_SECRET_REGEX, () => {\n bump();\n return REDACTED_SECRET;\n });\n text = text.replace(URL_REGEX, (match) => {\n const { core, trailing } = trimTrailingUrlPunctuation(match);\n let url: URL;\n try {\n url = new URL(core);\n } catch {\n // Not a parseable URL; leave it untouched rather than guess.\n return match;\n }\n if (isPreservedPublicUrl(url)) {\n return match;\n }\n bump();\n return `${REDACTED_URL}${trailing}`;\n });\n text = text.replace(EMAIL_REGEX, () => {\n bump();\n return REDACTED_EMAIL;\n });\n text = text.replace(UUID_REGEX, () => {\n bump();\n return REDACTED_ID;\n });\n text = text.replace(IPV4_REGEX, () => {\n bump();\n return REDACTED_IP;\n });\n text = text.replace(IPV6_REGEX, () => {\n bump();\n return REDACTED_IP;\n });\n\n return { text, redactions };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,MAAM,iBAAiB;AACvB,MAAM,cAAc;AACpB,MAAM,kBAAkB;AACxB,MAAM,eAAe;AACrB,MAAM,cAAc;AAEpB,MAAM,wBAAwB,QAC5B,IAAI,aAAa,MACjB,IAAI,aAAa,MACjB,IAAI,WAAW,MACf,IAAI,SAAS;;;;;;AAOf,MAAM,wBAAwB,QAAsB;CAClD,IAAI,CAAC,qBAAqB,GAAG,GAC3B,OAAO;CAET,IAAI,IAAI,SAAS,YAAY,MAAM,cACjC,OAAO;CAET,OACE,IAAI,aAAa,uBACjB,IAAI,SAAS,WAAW,oBAAoB;AAEhD;AAIA,MAAM,YACJ;AAGF,MAAM,mBAAmB;AAOzB,MAAM,sBAAsB;AAK5B,MAAM,YAAY;AAClB,MAAM,iCAAiC;AAEvC,MAAM,cAAc;AAEpB,MAAM,aACJ;AAEF,MAAM,aAAa;AAKnB,MAAM,aACJ;AAIF,MAAM,8BACJ,UACuC;CACvC,IAAI,OAAO;CACX,IAAI,WAAW;CAEf,MAAM,sBACJ,+BAA+B,KAAK,IAAI,CAAC,GAAG,MAAM;CACpD,IAAI,oBAAoB,SAAS,GAAG;EAClC,OAAO,KAAK,MAAM,GAAG,CAAC,oBAAoB,MAAM;EAChD,WAAW;CACb;CAEA,MAAM,QAAQ;EACZ;GAAE,MAAM;GAAK,OAAO;EAAI;EACxB;GAAE,MAAM;GAAK,OAAO;EAAI;EACxB;GAAE,MAAM;GAAK,OAAO;EAAI;CAC1B;CACA,IAAI,UAAU;CACd,OAAO,SAAS;EACd,UAAU;EACV,KAAK,MAAM,EAAE,OAAO,UAAU,OAAO;GACnC,IAAI,CAAC,KAAK,SAAS,KAAK,GACtB;GAEF,MAAM,QAAQ,MAAM,KAAK,IAAI,CAAC,CAAC,QAAQ,SAAS,SAAS,IAAI,CAAC,CAAC;GAE/D,IADe,MAAM,KAAK,IAAI,CAAC,CAAC,QAAQ,SAAS,SAAS,KAAK,CAAC,CAAC,UACnD,OACZ;GAEF,OAAO,KAAK,MAAM,GAAG,CAAC,MAAM,MAAM;GAClC,WAAW,GAAG,QAAQ;GACtB,UAAU;EACZ;CACF;CAEA,OAAO;EAAE;EAAM;CAAS;AAC1B;;;;;;;AAQA,MAAa,wBAAwB,UAA0C;CAC7E,IAAI,aAAa;CACjB,MAAM,aAAmB;EACvB,cAAc;CAChB;CAEA,IAAI,OAAO;CAEX,OAAO,KAAK,QAAQ,iBAAiB;EACnC,KAAK;EACL,OAAO;CACT,CAAC;CACD,OAAO,KAAK,QAAQ,wBAAwB;EAC1C,KAAK;EACL,OAAO;CACT,CAAC;CACD,OAAO,KAAK,QAAQ,2BAA2B;EAC7C,KAAK;EACL,OAAO;CACT,CAAC;CACD,OAAO,KAAK,QAAQ,YAAY,UAAU;EACxC,MAAM,EAAE,MAAM,aAAa,2BAA2B,KAAK;EAC3D,IAAI;EACJ,IAAI;GACF,MAAM,IAAI,IAAI,IAAI;EACpB,QAAQ;GAEN,OAAO;EACT;EACA,IAAI,qBAAqB,GAAG,GAC1B,OAAO;EAET,KAAK;EACL,OAAO,GAAG,eAAe;CAC3B,CAAC;CACD,OAAO,KAAK,QAAQ,mBAAmB;EACrC,KAAK;EACL,OAAO;CACT,CAAC;CACD,OAAO,KAAK,QAAQ,kBAAkB;EACpC,KAAK;EACL,OAAO;CACT,CAAC;CACD,OAAO,KAAK,QAAQ,kBAAkB;EACpC,KAAK;EACL,OAAO;CACT,CAAC;CACD,OAAO,KAAK,QAAQ,kBAAkB;EACpC,KAAK;EACL,OAAO;CACT,CAAC;CAED,OAAO;EAAE;EAAM;CAAW;AAC5B"}
@@ -0,0 +1,39 @@
1
+ //#region src/feedback.d.ts
2
+ /**
3
+ * Feedback submission builder shared by both agent surfaces.
4
+ *
5
+ * anonymize runs fully local and makes no network calls, so feedback is never
6
+ * sent from here. Instead this module sanitizes the agent-authored title/body
7
+ * and returns a prefilled GitHub new-issue URL (plus an equivalent `gh` command)
8
+ * that a human opens and submits under their own account. The human approval and
9
+ * the absence of any network call are the real controls; the sanitizer is a
10
+ * coarse safety net. This module stays runtime-free.
11
+ */
12
+ declare const FEEDBACK_KINDS: readonly ["bug", "feature_request", "docs", "other"];
13
+ type FeedbackKind = (typeof FEEDBACK_KINDS)[number];
14
+ declare const MAX_FEEDBACK_TITLE_CHARS = 200;
15
+ declare const MAX_FEEDBACK_BODY_CHARS = 8000;
16
+ type FeedbackInput = {
17
+ kind: FeedbackKind;
18
+ title: string;
19
+ body: string;
20
+ };
21
+ type FeedbackSubmission = {
22
+ title: string;
23
+ /** Fully sanitized body with a provenance footer; nothing is lost to URL truncation. */
24
+ sanitizedBody: string;
25
+ /** Total redactions across title and body, for the human to gauge stripping. */
26
+ redactions: number;
27
+ /** Prefilled new-issue URL the human opens and submits. */
28
+ issueUrl: string;
29
+ /** Equivalent `gh` command, safe to paste verbatim. */
30
+ ghCommand: string;
31
+ };
32
+ /**
33
+ * Sanitize the title and body, then build the prefilled GitHub submission. Pure:
34
+ * no I/O and no network. The caller presents the result for a human to submit.
35
+ */
36
+ declare const buildFeedbackSubmission: ({ body, kind, title }: FeedbackInput) => FeedbackSubmission;
37
+ //#endregion
38
+ export { FEEDBACK_KINDS, FeedbackKind, FeedbackSubmission, MAX_FEEDBACK_BODY_CHARS, MAX_FEEDBACK_TITLE_CHARS, buildFeedbackSubmission };
39
+ //# sourceMappingURL=feedback.d.mts.map
@@ -0,0 +1,84 @@
1
+ import { sanitizeFeedbackText } from "./feedback-sanitize.mjs";
2
+ //#region src/feedback.ts
3
+ /**
4
+ * Feedback submission builder shared by both agent surfaces.
5
+ *
6
+ * anonymize runs fully local and makes no network calls, so feedback is never
7
+ * sent from here. Instead this module sanitizes the agent-authored title/body
8
+ * and returns a prefilled GitHub new-issue URL (plus an equivalent `gh` command)
9
+ * that a human opens and submits under their own account. The human approval and
10
+ * the absence of any network call are the real controls; the sanitizer is a
11
+ * coarse safety net. This module stays runtime-free.
12
+ */
13
+ const FEEDBACK_KINDS = [
14
+ "bug",
15
+ "feature_request",
16
+ "docs",
17
+ "other"
18
+ ];
19
+ const MAX_FEEDBACK_TITLE_CHARS = 200;
20
+ const MAX_FEEDBACK_BODY_CHARS = 8e3;
21
+ const GITHUB_REPO = "stella/anonymize";
22
+ const GITHUB_ISSUE_LABEL = "agent-feedback";
23
+ const GITHUB_NEW_ISSUE_URL = `https://github.com/${GITHUB_REPO}/issues/new`;
24
+ const MAX_GITHUB_ISSUE_URL_CHARS = 7500;
25
+ const GITHUB_BODY_TRUNCATION_MARKER = "\n\n[body truncated — paste the rest manually]";
26
+ const HIGH_SURROGATE_START = 55296;
27
+ const HIGH_SURROGATE_END = 56319;
28
+ const composeFeedbackBody = (body, kind) => `${body}\n\n---\n_Filed via stella-anonymize feedback (agent-assisted, sanitized). Kind: ${kind}._`;
29
+ const buildGithubIssueUrl = (title, body) => {
30
+ const params = new URLSearchParams({
31
+ title,
32
+ body,
33
+ labels: GITHUB_ISSUE_LABEL
34
+ });
35
+ return `${GITHUB_NEW_ISSUE_URL}?${params.toString()}`;
36
+ };
37
+ const sliceWithoutDanglingHighSurrogate = (value, end) => {
38
+ const sliced = value.slice(0, end);
39
+ const last = sliced.codePointAt(sliced.length - 1);
40
+ return last !== void 0 && last >= HIGH_SURROGATE_START && last <= HIGH_SURROGATE_END ? sliced.slice(0, -1) : sliced;
41
+ };
42
+ /**
43
+ * Prefilled issue URL bounded to `MAX_GITHUB_ISSUE_URL_CHARS`. When the full
44
+ * body overflows, the URL carries a truncated body with a paste-the-rest marker;
45
+ * the caller still returns the full sanitized body separately.
46
+ */
47
+ const buildBoundedGithubIssueUrl = (title, composedBody) => {
48
+ const full = buildGithubIssueUrl(title, composedBody);
49
+ if (full.length <= MAX_GITHUB_ISSUE_URL_CHARS) return full;
50
+ for (let keep = composedBody.length; keep > 0; keep -= 128) {
51
+ const candidate = buildGithubIssueUrl(title, sliceWithoutDanglingHighSurrogate(composedBody, keep) + GITHUB_BODY_TRUNCATION_MARKER);
52
+ if (candidate.length <= MAX_GITHUB_ISSUE_URL_CHARS) return candidate;
53
+ }
54
+ return buildGithubIssueUrl(title, GITHUB_BODY_TRUNCATION_MARKER);
55
+ };
56
+ /** POSIX single-quote escaping so the gh command is safe to paste verbatim. */
57
+ const shellSingleQuote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
58
+ const buildGhCommand = (title, body) => [
59
+ "gh issue create",
60
+ `--repo ${GITHUB_REPO}`,
61
+ `--label ${GITHUB_ISSUE_LABEL}`,
62
+ `--title ${shellSingleQuote(title)}`,
63
+ `--body ${shellSingleQuote(body)}`
64
+ ].join(" ");
65
+ /**
66
+ * Sanitize the title and body, then build the prefilled GitHub submission. Pure:
67
+ * no I/O and no network. The caller presents the result for a human to submit.
68
+ */
69
+ const buildFeedbackSubmission = ({ body, kind, title }) => {
70
+ const cleanTitle = sanitizeFeedbackText(title);
71
+ const cleanBody = sanitizeFeedbackText(body);
72
+ const composedBody = composeFeedbackBody(cleanBody.text, kind);
73
+ return {
74
+ title: cleanTitle.text,
75
+ sanitizedBody: composedBody,
76
+ redactions: cleanTitle.redactions + cleanBody.redactions,
77
+ issueUrl: buildBoundedGithubIssueUrl(cleanTitle.text, composedBody),
78
+ ghCommand: buildGhCommand(cleanTitle.text, composedBody)
79
+ };
80
+ };
81
+ //#endregion
82
+ export { FEEDBACK_KINDS, MAX_FEEDBACK_BODY_CHARS, MAX_FEEDBACK_TITLE_CHARS, buildFeedbackSubmission };
83
+
84
+ //# sourceMappingURL=feedback.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.mjs","names":[],"sources":["../src/feedback.ts"],"sourcesContent":["/**\n * Feedback submission builder shared by both agent surfaces.\n *\n * anonymize runs fully local and makes no network calls, so feedback is never\n * sent from here. Instead this module sanitizes the agent-authored title/body\n * and returns a prefilled GitHub new-issue URL (plus an equivalent `gh` command)\n * that a human opens and submits under their own account. The human approval and\n * the absence of any network call are the real controls; the sanitizer is a\n * coarse safety net. This module stays runtime-free.\n */\n\nimport {\n sanitizeFeedbackText,\n type SanitizeFeedbackResult,\n} from \"./feedback-sanitize\";\n\nexport const FEEDBACK_KINDS = [\n \"bug\",\n \"feature_request\",\n \"docs\",\n \"other\",\n] as const;\nexport type FeedbackKind = (typeof FEEDBACK_KINDS)[number];\n\nexport const MAX_FEEDBACK_TITLE_CHARS = 200;\nexport const MAX_FEEDBACK_BODY_CHARS = 8000;\n\nconst GITHUB_REPO = \"stella/anonymize\";\nconst GITHUB_ISSUE_LABEL = \"agent-feedback\";\nconst GITHUB_NEW_ISSUE_URL = `https://github.com/${GITHUB_REPO}/issues/new`;\n// A conservative cap: browsers accept much longer, but keeping the prefilled URL\n// small avoids client-side truncation surprises. The full sanitized body is\n// always returned separately, so nothing is lost.\nconst MAX_GITHUB_ISSUE_URL_CHARS = 7500;\nconst GITHUB_BODY_TRUNCATION_MARKER =\n \"\\n\\n[body truncated — paste the rest manually]\";\nconst HIGH_SURROGATE_START = 55_296;\nconst HIGH_SURROGATE_END = 56_319;\n\ntype FeedbackInput = {\n kind: FeedbackKind;\n title: string;\n body: string;\n};\n\nexport type FeedbackSubmission = {\n title: string;\n /** Fully sanitized body with a provenance footer; nothing is lost to URL truncation. */\n sanitizedBody: string;\n /** Total redactions across title and body, for the human to gauge stripping. */\n redactions: number;\n /** Prefilled new-issue URL the human opens and submits. */\n issueUrl: string;\n /** Equivalent `gh` command, safe to paste verbatim. */\n ghCommand: string;\n};\n\nconst composeFeedbackBody = (body: string, kind: FeedbackKind): string =>\n `${body}\\n\\n---\\n_Filed via stella-anonymize feedback (agent-assisted, sanitized). Kind: ${kind}._`;\n\nconst buildGithubIssueUrl = (title: string, body: string): string => {\n const params = new URLSearchParams({\n title,\n body,\n labels: GITHUB_ISSUE_LABEL,\n });\n return `${GITHUB_NEW_ISSUE_URL}?${params.toString()}`;\n};\n\nconst sliceWithoutDanglingHighSurrogate = (\n value: string,\n end: number,\n): string => {\n const sliced = value.slice(0, end);\n const last = sliced.codePointAt(sliced.length - 1);\n return last !== undefined &&\n last >= HIGH_SURROGATE_START &&\n last <= HIGH_SURROGATE_END\n ? sliced.slice(0, -1)\n : sliced;\n};\n\n/**\n * Prefilled issue URL bounded to `MAX_GITHUB_ISSUE_URL_CHARS`. When the full\n * body overflows, the URL carries a truncated body with a paste-the-rest marker;\n * the caller still returns the full sanitized body separately.\n */\nconst buildBoundedGithubIssueUrl = (\n title: string,\n composedBody: string,\n): string => {\n const full = buildGithubIssueUrl(title, composedBody);\n if (full.length <= MAX_GITHUB_ISSUE_URL_CHARS) {\n return full;\n }\n for (let keep = composedBody.length; keep > 0; keep -= 128) {\n const candidate = buildGithubIssueUrl(\n title,\n sliceWithoutDanglingHighSurrogate(composedBody, keep) +\n GITHUB_BODY_TRUNCATION_MARKER,\n );\n if (candidate.length <= MAX_GITHUB_ISSUE_URL_CHARS) {\n return candidate;\n }\n }\n // Even an empty body overflows (an outsized title): fall back to marker-only.\n return buildGithubIssueUrl(title, GITHUB_BODY_TRUNCATION_MARKER);\n};\n\n/** POSIX single-quote escaping so the gh command is safe to paste verbatim. */\nconst shellSingleQuote = (value: string): string =>\n `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n\nconst buildGhCommand = (title: string, body: string): string =>\n [\n \"gh issue create\",\n `--repo ${GITHUB_REPO}`,\n `--label ${GITHUB_ISSUE_LABEL}`,\n `--title ${shellSingleQuote(title)}`,\n `--body ${shellSingleQuote(body)}`,\n ].join(\" \");\n\n/**\n * Sanitize the title and body, then build the prefilled GitHub submission. Pure:\n * no I/O and no network. The caller presents the result for a human to submit.\n */\nexport const buildFeedbackSubmission = ({\n body,\n kind,\n title,\n}: FeedbackInput): FeedbackSubmission => {\n const cleanTitle: SanitizeFeedbackResult = sanitizeFeedbackText(title);\n const cleanBody = sanitizeFeedbackText(body);\n const composedBody = composeFeedbackBody(cleanBody.text, kind);\n return {\n title: cleanTitle.text,\n sanitizedBody: composedBody,\n redactions: cleanTitle.redactions + cleanBody.redactions,\n issueUrl: buildBoundedGithubIssueUrl(cleanTitle.text, composedBody),\n ghCommand: buildGhCommand(cleanTitle.text, composedBody),\n };\n};\n"],"mappings":";;;;;;;;;;;;AAgBA,MAAa,iBAAiB;CAC5B;CACA;CACA;CACA;AACF;AAGA,MAAa,2BAA2B;AACxC,MAAa,0BAA0B;AAEvC,MAAM,cAAc;AACpB,MAAM,qBAAqB;AAC3B,MAAM,uBAAuB,sBAAsB,YAAY;AAI/D,MAAM,6BAA6B;AACnC,MAAM,gCACJ;AACF,MAAM,uBAAuB;AAC7B,MAAM,qBAAqB;AAoB3B,MAAM,uBAAuB,MAAc,SACzC,GAAG,KAAK,mFAAmF,KAAK;AAElG,MAAM,uBAAuB,OAAe,SAAyB;CACnE,MAAM,SAAS,IAAI,gBAAgB;EACjC;EACA;EACA,QAAQ;CACV,CAAC;CACD,OAAO,GAAG,qBAAqB,GAAG,OAAO,SAAS;AACpD;AAEA,MAAM,qCACJ,OACA,QACW;CACX,MAAM,SAAS,MAAM,MAAM,GAAG,GAAG;CACjC,MAAM,OAAO,OAAO,YAAY,OAAO,SAAS,CAAC;CACjD,OAAO,SAAS,KAAA,KACd,QAAQ,wBACR,QAAQ,qBACN,OAAO,MAAM,GAAG,EAAE,IAClB;AACN;;;;;;AAOA,MAAM,8BACJ,OACA,iBACW;CACX,MAAM,OAAO,oBAAoB,OAAO,YAAY;CACpD,IAAI,KAAK,UAAU,4BACjB,OAAO;CAET,KAAK,IAAI,OAAO,aAAa,QAAQ,OAAO,GAAG,QAAQ,KAAK;EAC1D,MAAM,YAAY,oBAChB,OACA,kCAAkC,cAAc,IAAI,IAClD,6BACJ;EACA,IAAI,UAAU,UAAU,4BACtB,OAAO;CAEX;CAEA,OAAO,oBAAoB,OAAO,6BAA6B;AACjE;;AAGA,MAAM,oBAAoB,UACxB,IAAI,MAAM,WAAW,KAAK,OAAO,EAAE;AAErC,MAAM,kBAAkB,OAAe,SACrC;CACE;CACA,UAAU;CACV,WAAW;CACX,WAAW,iBAAiB,KAAK;CACjC,UAAU,iBAAiB,IAAI;AACjC,CAAC,CAAC,KAAK,GAAG;;;;;AAMZ,MAAa,2BAA2B,EACtC,MACA,MACA,YACuC;CACvC,MAAM,aAAqC,qBAAqB,KAAK;CACrE,MAAM,YAAY,qBAAqB,IAAI;CAC3C,MAAM,eAAe,oBAAoB,UAAU,MAAM,IAAI;CAC7D,OAAO;EACL,OAAO,WAAW;EAClB,eAAe;EACf,YAAY,WAAW,aAAa,UAAU;EAC9C,UAAU,2BAA2B,WAAW,MAAM,YAAY;EAClE,WAAW,eAAe,WAAW,MAAM,YAAY;CACzD;AACF"}
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { a as DetectionSource, c as ENTITY_SELECTIONS, d as EntitySelection, f as OPERATOR_TYPES, i as DefaultEntityLabel, l as EntityCapability, n as DETECTION_SOURCES, o as ENTITY_CAPABILITIES, p as OperatorType, r as DETECTOR_PRIORITY, s as ENTITY_LABELS, t as DEFAULT_ENTITY_LABELS, u as EntityLabel } from "./constants2.mjs";
2
2
  import { CAPABILITY_MANIFEST, CAPABILITY_MANIFEST_SCHEMA_VERSION, CAPABILITY_PARITY_PROFILES, CAPABILITY_RUNTIMES, CAPABILITY_SURFACES, CapabilityManifest, CapabilityParityProfile, CapabilityRuntime, CapabilitySurface, CapabilitySurfaceId } from "./capabilities.mjs";
3
3
  import { $ as SharedNativeRedactTextOptions, A as NativeResultEventCallback, At as PipelineConfig, B as NativeSessionStatus, C as NativeOperatorConfig, Ct as CustomRegexPattern, D as NativePreparedSearchBinding, Dt as Entity, E as NativePreparedRedactionSessionBinding, Et as DictionaryMeta, F as NativeSessionCallerRedactionPlanOptions, Ft as TriggerGroupConfig, G as PreparedNativePipeline, H as NativeTextReplacement, I as NativeSessionDeletionSummary, It as TriggerRule, J as PreparedSearch, K as PreparedNativeRedactionSession, L as NativeSessionLifecycle, Lt as TriggerStrategy, M as NativeSearchPackageOptions, Mt as ReviewDecision, N as NativeSessionBlockRedactionPlan, Nt as ReviewedEntity, O as NativePreparedSessionRedactionPlanBinding, Ot as GazetteerEntry, P as NativeSessionCallerRedactionInput, Pt as TriggerExtension, Q as SharedNativeRedactTextJsonOptions, R as NativeSessionMetadata, Rt as TriggerValidation, S as NativeOpenSessionArchiveOptions, St as CustomDenyListEntry, T as NativePipelineFromPackageOptions, Tt as Dictionaries, U as PreparedAnonymizer, V as NativeStaticRedactionResult, W as PreparedNativeAnonymizer, X as SharedNativeDiagnosticsStreamJsonOptions, Y as SharedNativeDiagnosticsJsonOptions, Z as SharedNativePreparedPackageOptions, _ as NativeCallerDetection, a as EXTERNAL_DETECTION_DOCUMENT_MAX_BYTES, at as createNativeAnonymizerFromPackage, b as NativeDiagnosticsBatchCallback, c as EXTERNAL_DETECTION_MAX_METADATA_BYTES, d as ExternalDetectionBatch, dt as getNativeBindingVersion, et as SharedNativeRedactTextStreamJsonOptions, f as ExternalDetectionOffsetUnit, g as NativeBindingVersionOptions, h as NativeAnonymizerFromPackageOptions, ht as prepareNativeSearchPackage, i as EXTERNAL_DETECTION_BATCH_VERSION, it as createNativeAnonymizerFromConfig, j as NativeSearchPackageInput, jt as RedactionResult, k as NativeRedactionResult, kt as OperatorConfig, l as EXTERNAL_DETECTION_OFFSET_UNITS, lt as encodeNativeSearchConfig, m as NativeAnonymizerFromConfigOptions, n as ConvertExternalDetectionBatchOptions, nt as assertNativeBindingVersion, o as EXTERNAL_DETECTION_MAX_DETECTIONS, ot as createNativePipelineFromPackage, p as NativeAnonymizeBinding, q as PreparedNativeSessionRedactionPlan, r as EXTERNAL_DETECTION_BATCH_MAX_BYTES, s as EXTERNAL_DETECTION_MAX_LABEL_MAPPINGS, t as CALLER_DETECTION_CONTRACT_VERSION, tt as SharedNativeSearchPackageOptions, u as EXTERNAL_DETECTION_PROVIDER_ID_MAX_BYTES, ut as encodeNativeSearchConfigInput, v as NativeCallerRedactionOptions, w as NativePipelineEntity, wt as DenyListCategory, x as NativeNormalizeOptions, xt as AnonymisationOperator, y as NativeCreateSessionWithLifecycleOptions, z as NativeSessionRedactionAtOptions, zt as NativePreparedSearchConfig } from "./native.mjs";
4
- import { A as readDefaultNativePipelinePackageFile, B as redact_text_json, C as load_prepared_package_file, D as preloadDefaultNativePipelineAsync, E as preloadDefaultNativePipeline, F as redactDefaultText, G as NativePipelineCompatibility, H as summary_diagnostics_json, I as redactDefaultTextJson, J as assertNativePipelineSupported, K as NativePipelinePackageOptions, L as redact_default_text, M as readNativePipelinePackageFile, N as readNativePipelinePackageFileAsync, O as preload_default_native_pipeline, P as read_default_native_pipeline_package_file, Q as prepareNativePipelinePackage, R as redact_default_text_json, S as load_prepared_package, T as normalize_for_search, U as DEFAULT_NATIVE_PIPELINE_CONFIG, V as redact_text_stream_json, W as NativePipelineBuildOptions, X as getNativePipelineCompatibility, Y as createNativePipelineFromConfig, Z as prepareNativePipelineConfig, _ as diagnostics_json, a as LoadNativeBindingOptions, b as get_default_native_pipeline, c as NativeRequire, d as availableDefaultNativePipelineLanguages, f as available_default_native_pipeline_languages, g as create_native_pipeline_from_default_package, h as createNativePipelineFromPackageFile, i as DefaultNativePipelineWarmup, j as readDefaultNativePipelinePackageFileAsync, k as prepare_search_package, l as NativeSdkOptions, m as createNativePipelineFromDefaultPackage, n as DefaultNativePipelinePackageFileOptions, o as NativeLibc, p as convert_external_detection_batch, q as NativePipelineUnsupportedFeature, r as DefaultNativePipelinePackageOptions, s as NativePipelinePackageFileOptions, t as DEFAULT_NATIVE_PIPELINE_WARMUPS, u as NativeSdkPackageOptions, v as diagnostics_stream_json, w as native_package_version, x as loadNativeAnonymizeBinding, y as getDefaultNativePipeline, z as redact_text } from "./native-node.mjs";
4
+ import { $ as prepareNativePipelinePackage, A as readDefaultNativePipelinePackageFile, B as redact_text_json, C as load_prepared_package_file, D as preloadDefaultNativePipelineAsync, E as preloadDefaultNativePipeline, F as redactDefaultText, G as NativePipelineBuildOptions, H as setNativeBindingOverride, I as redactDefaultTextJson, J as NativePipelineUnsupportedFeature, K as NativePipelineCompatibility, L as redact_default_text, M as readNativePipelinePackageFile, N as readNativePipelinePackageFileAsync, O as preload_default_native_pipeline, P as read_default_native_pipeline_package_file, Q as prepareNativePipelineConfig, R as redact_default_text_json, S as load_prepared_package, T as normalize_for_search, U as summary_diagnostics_json, V as redact_text_stream_json, W as DEFAULT_NATIVE_PIPELINE_CONFIG, X as createNativePipelineFromConfig, Y as assertNativePipelineSupported, Z as getNativePipelineCompatibility, _ as diagnostics_json, a as LoadNativeBindingOptions, b as get_default_native_pipeline, c as NativeRequire, d as availableDefaultNativePipelineLanguages, f as available_default_native_pipeline_languages, g as create_native_pipeline_from_default_package, h as createNativePipelineFromPackageFile, i as DefaultNativePipelineWarmup, j as readDefaultNativePipelinePackageFileAsync, k as prepare_search_package, l as NativeSdkOptions, m as createNativePipelineFromDefaultPackage, n as DefaultNativePipelinePackageFileOptions, o as NativeLibc, p as convert_external_detection_batch, q as NativePipelinePackageOptions, r as DefaultNativePipelinePackageOptions, s as NativePipelinePackageFileOptions, t as DEFAULT_NATIVE_PIPELINE_WARMUPS, u as NativeSdkPackageOptions, v as diagnostics_stream_json, w as native_package_version, x as loadNativeAnonymizeBinding, y as getDefaultNativePipeline, z as redact_text } from "./native-node.mjs";
5
5
  //#region src/redact.d.ts
6
6
  /**
7
7
  * Serialize the redaction key to JSON for export.
@@ -15,5 +15,5 @@ declare const exportRedactionKey: (redactionMap: Map<string, string>, operatorMa
15
15
  */
16
16
  declare const deanonymise: (redactedText: string, redactionMap: Map<string, string>) => string;
17
17
  //#endregion
18
- export { type AnonymisationOperator, CALLER_DETECTION_CONTRACT_VERSION, CAPABILITY_MANIFEST, CAPABILITY_MANIFEST_SCHEMA_VERSION, CAPABILITY_PARITY_PROFILES, CAPABILITY_RUNTIMES, CAPABILITY_SURFACES, type CapabilityManifest, type CapabilityParityProfile, type CapabilityRuntime, type CapabilitySurface, type CapabilitySurfaceId, ConvertExternalDetectionBatchOptions, type CustomDenyListEntry, type CustomRegexPattern, DEFAULT_ENTITY_LABELS, DEFAULT_NATIVE_PIPELINE_CONFIG, DEFAULT_NATIVE_PIPELINE_WARMUPS, DETECTION_SOURCES, DETECTOR_PRIORITY, type DefaultEntityLabel, DefaultNativePipelinePackageFileOptions, DefaultNativePipelinePackageOptions, DefaultNativePipelineWarmup, type DenyListCategory, type DetectionSource, type Dictionaries, type DictionaryMeta, ENTITY_CAPABILITIES, ENTITY_LABELS, ENTITY_SELECTIONS, EXTERNAL_DETECTION_BATCH_MAX_BYTES, EXTERNAL_DETECTION_BATCH_VERSION, EXTERNAL_DETECTION_DOCUMENT_MAX_BYTES, EXTERNAL_DETECTION_MAX_DETECTIONS, EXTERNAL_DETECTION_MAX_LABEL_MAPPINGS, EXTERNAL_DETECTION_MAX_METADATA_BYTES, EXTERNAL_DETECTION_OFFSET_UNITS, EXTERNAL_DETECTION_PROVIDER_ID_MAX_BYTES, type Entity, type EntityCapability, type EntityLabel, type EntitySelection, ExternalDetectionBatch, ExternalDetectionOffsetUnit, type GazetteerEntry, LoadNativeBindingOptions, NativeAnonymizeBinding, NativeAnonymizerFromConfigOptions, NativeAnonymizerFromPackageOptions, NativeBindingVersionOptions, NativeCallerDetection, NativeCallerRedactionOptions, NativeCreateSessionWithLifecycleOptions, NativeDiagnosticsBatchCallback, NativeLibc, NativeNormalizeOptions, NativeOpenSessionArchiveOptions, NativeOperatorConfig, type NativePipelineBuildOptions, type NativePipelineCompatibility, NativePipelineEntity, NativePipelineFromPackageOptions, NativePipelinePackageFileOptions, type NativePipelinePackageOptions, type NativePipelineUnsupportedFeature, NativePreparedRedactionSessionBinding, NativePreparedSearchBinding, type NativePreparedSearchConfig, NativePreparedSessionRedactionPlanBinding, NativeRedactionResult, NativeRequire, NativeResultEventCallback, NativeSdkOptions, NativeSdkPackageOptions, NativeSearchPackageInput, NativeSearchPackageOptions, NativeSessionBlockRedactionPlan, NativeSessionCallerRedactionInput, NativeSessionCallerRedactionPlanOptions, NativeSessionDeletionSummary, NativeSessionLifecycle, NativeSessionMetadata, NativeSessionRedactionAtOptions, NativeSessionStatus, NativeStaticRedactionResult, NativeTextReplacement, OPERATOR_TYPES, type OperatorConfig, type OperatorType, type PipelineConfig, PreparedAnonymizer, PreparedNativeAnonymizer, PreparedNativePipeline, PreparedNativeRedactionSession, PreparedNativeSessionRedactionPlan, PreparedSearch, type RedactionResult, type ReviewDecision, type ReviewedEntity, SharedNativeDiagnosticsJsonOptions, SharedNativeDiagnosticsStreamJsonOptions, SharedNativePreparedPackageOptions, SharedNativeRedactTextJsonOptions, SharedNativeRedactTextOptions, SharedNativeRedactTextStreamJsonOptions, SharedNativeSearchPackageOptions, type TriggerExtension, type TriggerGroupConfig, type TriggerRule, type TriggerStrategy, type TriggerValidation, assertNativeBindingVersion, assertNativePipelineSupported, availableDefaultNativePipelineLanguages, available_default_native_pipeline_languages, convert_external_detection_batch, createNativeAnonymizerFromConfig, createNativeAnonymizerFromPackage, createNativePipelineFromConfig, createNativePipelineFromDefaultPackage, createNativePipelineFromPackage, createNativePipelineFromPackageFile, create_native_pipeline_from_default_package, deanonymise, diagnostics_json, diagnostics_stream_json, encodeNativeSearchConfig, encodeNativeSearchConfigInput, exportRedactionKey, getDefaultNativePipeline, getNativeBindingVersion, getNativePipelineCompatibility, get_default_native_pipeline, loadNativeAnonymizeBinding, load_prepared_package, load_prepared_package_file, native_package_version, normalize_for_search, preloadDefaultNativePipeline, preloadDefaultNativePipelineAsync, preload_default_native_pipeline, prepareNativePipelineConfig, prepareNativePipelinePackage, prepareNativeSearchPackage, prepare_search_package, readDefaultNativePipelinePackageFile, readDefaultNativePipelinePackageFileAsync, readNativePipelinePackageFile, readNativePipelinePackageFileAsync, read_default_native_pipeline_package_file, redactDefaultText, redactDefaultTextJson, redact_default_text, redact_default_text_json, redact_text, redact_text_json, redact_text_stream_json, summary_diagnostics_json };
18
+ export { type AnonymisationOperator, CALLER_DETECTION_CONTRACT_VERSION, CAPABILITY_MANIFEST, CAPABILITY_MANIFEST_SCHEMA_VERSION, CAPABILITY_PARITY_PROFILES, CAPABILITY_RUNTIMES, CAPABILITY_SURFACES, type CapabilityManifest, type CapabilityParityProfile, type CapabilityRuntime, type CapabilitySurface, type CapabilitySurfaceId, ConvertExternalDetectionBatchOptions, type CustomDenyListEntry, type CustomRegexPattern, DEFAULT_ENTITY_LABELS, DEFAULT_NATIVE_PIPELINE_CONFIG, DEFAULT_NATIVE_PIPELINE_WARMUPS, DETECTION_SOURCES, DETECTOR_PRIORITY, type DefaultEntityLabel, DefaultNativePipelinePackageFileOptions, DefaultNativePipelinePackageOptions, DefaultNativePipelineWarmup, type DenyListCategory, type DetectionSource, type Dictionaries, type DictionaryMeta, ENTITY_CAPABILITIES, ENTITY_LABELS, ENTITY_SELECTIONS, EXTERNAL_DETECTION_BATCH_MAX_BYTES, EXTERNAL_DETECTION_BATCH_VERSION, EXTERNAL_DETECTION_DOCUMENT_MAX_BYTES, EXTERNAL_DETECTION_MAX_DETECTIONS, EXTERNAL_DETECTION_MAX_LABEL_MAPPINGS, EXTERNAL_DETECTION_MAX_METADATA_BYTES, EXTERNAL_DETECTION_OFFSET_UNITS, EXTERNAL_DETECTION_PROVIDER_ID_MAX_BYTES, type Entity, type EntityCapability, type EntityLabel, type EntitySelection, ExternalDetectionBatch, ExternalDetectionOffsetUnit, type GazetteerEntry, LoadNativeBindingOptions, NativeAnonymizeBinding, NativeAnonymizerFromConfigOptions, NativeAnonymizerFromPackageOptions, NativeBindingVersionOptions, NativeCallerDetection, NativeCallerRedactionOptions, NativeCreateSessionWithLifecycleOptions, NativeDiagnosticsBatchCallback, NativeLibc, NativeNormalizeOptions, NativeOpenSessionArchiveOptions, NativeOperatorConfig, type NativePipelineBuildOptions, type NativePipelineCompatibility, NativePipelineEntity, NativePipelineFromPackageOptions, NativePipelinePackageFileOptions, type NativePipelinePackageOptions, type NativePipelineUnsupportedFeature, NativePreparedRedactionSessionBinding, NativePreparedSearchBinding, type NativePreparedSearchConfig, NativePreparedSessionRedactionPlanBinding, NativeRedactionResult, NativeRequire, NativeResultEventCallback, NativeSdkOptions, NativeSdkPackageOptions, NativeSearchPackageInput, NativeSearchPackageOptions, NativeSessionBlockRedactionPlan, NativeSessionCallerRedactionInput, NativeSessionCallerRedactionPlanOptions, NativeSessionDeletionSummary, NativeSessionLifecycle, NativeSessionMetadata, NativeSessionRedactionAtOptions, NativeSessionStatus, NativeStaticRedactionResult, NativeTextReplacement, OPERATOR_TYPES, type OperatorConfig, type OperatorType, type PipelineConfig, PreparedAnonymizer, PreparedNativeAnonymizer, PreparedNativePipeline, PreparedNativeRedactionSession, PreparedNativeSessionRedactionPlan, PreparedSearch, type RedactionResult, type ReviewDecision, type ReviewedEntity, SharedNativeDiagnosticsJsonOptions, SharedNativeDiagnosticsStreamJsonOptions, SharedNativePreparedPackageOptions, SharedNativeRedactTextJsonOptions, SharedNativeRedactTextOptions, SharedNativeRedactTextStreamJsonOptions, SharedNativeSearchPackageOptions, type TriggerExtension, type TriggerGroupConfig, type TriggerRule, type TriggerStrategy, type TriggerValidation, assertNativeBindingVersion, assertNativePipelineSupported, availableDefaultNativePipelineLanguages, available_default_native_pipeline_languages, convert_external_detection_batch, createNativeAnonymizerFromConfig, createNativeAnonymizerFromPackage, createNativePipelineFromConfig, createNativePipelineFromDefaultPackage, createNativePipelineFromPackage, createNativePipelineFromPackageFile, create_native_pipeline_from_default_package, deanonymise, diagnostics_json, diagnostics_stream_json, encodeNativeSearchConfig, encodeNativeSearchConfigInput, exportRedactionKey, getDefaultNativePipeline, getNativeBindingVersion, getNativePipelineCompatibility, get_default_native_pipeline, loadNativeAnonymizeBinding, load_prepared_package, load_prepared_package_file, native_package_version, normalize_for_search, preloadDefaultNativePipeline, preloadDefaultNativePipelineAsync, preload_default_native_pipeline, prepareNativePipelineConfig, prepareNativePipelinePackage, prepareNativeSearchPackage, prepare_search_package, readDefaultNativePipelinePackageFile, readDefaultNativePipelinePackageFileAsync, readNativePipelinePackageFile, readNativePipelinePackageFileAsync, read_default_native_pipeline_package_file, redactDefaultText, redactDefaultTextJson, redact_default_text, redact_default_text_json, redact_text, redact_text_json, redact_text_stream_json, setNativeBindingOverride, summary_diagnostics_json };
19
19
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CALLER_DETECTION_CONTRACT_VERSION, EXTERNAL_DETECTION_BATCH_MAX_BYTES, EXTERNAL_DETECTION_BATCH_VERSION, EXTERNAL_DETECTION_DOCUMENT_MAX_BYTES, EXTERNAL_DETECTION_MAX_DETECTIONS, EXTERNAL_DETECTION_MAX_LABEL_MAPPINGS, EXTERNAL_DETECTION_MAX_METADATA_BYTES, EXTERNAL_DETECTION_OFFSET_UNITS, EXTERNAL_DETECTION_PROVIDER_ID_MAX_BYTES, PreparedAnonymizer, PreparedNativeAnonymizer, PreparedNativePipeline, PreparedNativeRedactionSession, PreparedNativeSessionRedactionPlan, PreparedSearch, assertNativeBindingVersion, createNativeAnonymizerFromConfig, createNativeAnonymizerFromPackage, createNativePipelineFromPackage, encodeNativeSearchConfig, encodeNativeSearchConfigInput, getNativeBindingVersion, prepareNativeSearchPackage } from "./native.mjs";
2
- import { A as redact_text, C as readNativePipelinePackageFile, D as redactDefaultTextJson, E as redactDefaultText, F as assertNativePipelineSupported, I as createNativePipelineFromConfig, L as getNativePipelineCompatibility, M as redact_text_stream_json, N as summary_diagnostics_json, O as redact_default_text, P as DEFAULT_NATIVE_PIPELINE_CONFIG, R as prepareNativePipelineConfig, S as readDefaultNativePipelinePackageFileAsync, T as read_default_native_pipeline_package_file, _ as preloadDefaultNativePipeline, a as createNativePipelineFromDefaultPackage, b as prepare_search_package, c as diagnostics_json, d as get_default_native_pipeline, f as loadNativeAnonymizeBinding, g as normalize_for_search, h as native_package_version, i as convert_external_detection_batch, j as redact_text_json, k as redact_default_text_json, l as diagnostics_stream_json, m as load_prepared_package_file, n as availableDefaultNativePipelineLanguages, o as createNativePipelineFromPackageFile, p as load_prepared_package, r as available_default_native_pipeline_languages, s as create_native_pipeline_from_default_package, t as DEFAULT_NATIVE_PIPELINE_WARMUPS, u as getDefaultNativePipeline, v as preloadDefaultNativePipelineAsync, w as readNativePipelinePackageFileAsync, x as readDefaultNativePipelinePackageFile, y as preload_default_native_pipeline, z as prepareNativePipelinePackage } from "./native-node2.mjs";
2
+ import { A as redact_text, B as prepareNativePipelinePackage, C as readNativePipelinePackageFile, D as redactDefaultTextJson, E as redactDefaultText, F as DEFAULT_NATIVE_PIPELINE_CONFIG, I as assertNativePipelineSupported, L as createNativePipelineFromConfig, M as redact_text_stream_json, N as setNativeBindingOverride, O as redact_default_text, P as summary_diagnostics_json, R as getNativePipelineCompatibility, S as readDefaultNativePipelinePackageFileAsync, T as read_default_native_pipeline_package_file, _ as preloadDefaultNativePipeline, a as createNativePipelineFromDefaultPackage, b as prepare_search_package, c as diagnostics_json, d as get_default_native_pipeline, f as loadNativeAnonymizeBinding, g as normalize_for_search, h as native_package_version, i as convert_external_detection_batch, j as redact_text_json, k as redact_default_text_json, l as diagnostics_stream_json, m as load_prepared_package_file, n as availableDefaultNativePipelineLanguages, o as createNativePipelineFromPackageFile, p as load_prepared_package, r as available_default_native_pipeline_languages, s as create_native_pipeline_from_default_package, t as DEFAULT_NATIVE_PIPELINE_WARMUPS, u as getDefaultNativePipeline, v as preloadDefaultNativePipelineAsync, w as readNativePipelinePackageFileAsync, x as readDefaultNativePipelinePackageFile, y as preload_default_native_pipeline, z as prepareNativePipelineConfig } from "./native-node2.mjs";
3
3
  import { DEFAULT_ENTITY_LABELS, DETECTION_SOURCES, DETECTOR_PRIORITY, ENTITY_CAPABILITIES, ENTITY_LABELS, ENTITY_SELECTIONS, OPERATOR_TYPES } from "./constants.mjs";
4
4
  import { CAPABILITY_MANIFEST, CAPABILITY_MANIFEST_SCHEMA_VERSION, CAPABILITY_PARITY_PROFILES, CAPABILITY_RUNTIMES, CAPABILITY_SURFACES } from "./capabilities.mjs";
5
5
  //#region src/redact.ts
@@ -26,6 +26,6 @@ const deanonymise = (redactedText, redactionMap) => {
26
26
  return result;
27
27
  };
28
28
  //#endregion
29
- export { CALLER_DETECTION_CONTRACT_VERSION, CAPABILITY_MANIFEST, CAPABILITY_MANIFEST_SCHEMA_VERSION, CAPABILITY_PARITY_PROFILES, CAPABILITY_RUNTIMES, CAPABILITY_SURFACES, DEFAULT_ENTITY_LABELS, DEFAULT_NATIVE_PIPELINE_CONFIG, DEFAULT_NATIVE_PIPELINE_WARMUPS, DETECTION_SOURCES, DETECTOR_PRIORITY, ENTITY_CAPABILITIES, ENTITY_LABELS, ENTITY_SELECTIONS, EXTERNAL_DETECTION_BATCH_MAX_BYTES, EXTERNAL_DETECTION_BATCH_VERSION, EXTERNAL_DETECTION_DOCUMENT_MAX_BYTES, EXTERNAL_DETECTION_MAX_DETECTIONS, EXTERNAL_DETECTION_MAX_LABEL_MAPPINGS, EXTERNAL_DETECTION_MAX_METADATA_BYTES, EXTERNAL_DETECTION_OFFSET_UNITS, EXTERNAL_DETECTION_PROVIDER_ID_MAX_BYTES, OPERATOR_TYPES, PreparedAnonymizer, PreparedNativeAnonymizer, PreparedNativePipeline, PreparedNativeRedactionSession, PreparedNativeSessionRedactionPlan, PreparedSearch, assertNativeBindingVersion, assertNativePipelineSupported, availableDefaultNativePipelineLanguages, available_default_native_pipeline_languages, convert_external_detection_batch, createNativeAnonymizerFromConfig, createNativeAnonymizerFromPackage, createNativePipelineFromConfig, createNativePipelineFromDefaultPackage, createNativePipelineFromPackage, createNativePipelineFromPackageFile, create_native_pipeline_from_default_package, deanonymise, diagnostics_json, diagnostics_stream_json, encodeNativeSearchConfig, encodeNativeSearchConfigInput, exportRedactionKey, getDefaultNativePipeline, getNativeBindingVersion, getNativePipelineCompatibility, get_default_native_pipeline, loadNativeAnonymizeBinding, load_prepared_package, load_prepared_package_file, native_package_version, normalize_for_search, preloadDefaultNativePipeline, preloadDefaultNativePipelineAsync, preload_default_native_pipeline, prepareNativePipelineConfig, prepareNativePipelinePackage, prepareNativeSearchPackage, prepare_search_package, readDefaultNativePipelinePackageFile, readDefaultNativePipelinePackageFileAsync, readNativePipelinePackageFile, readNativePipelinePackageFileAsync, read_default_native_pipeline_package_file, redactDefaultText, redactDefaultTextJson, redact_default_text, redact_default_text_json, redact_text, redact_text_json, redact_text_stream_json, summary_diagnostics_json };
29
+ export { CALLER_DETECTION_CONTRACT_VERSION, CAPABILITY_MANIFEST, CAPABILITY_MANIFEST_SCHEMA_VERSION, CAPABILITY_PARITY_PROFILES, CAPABILITY_RUNTIMES, CAPABILITY_SURFACES, DEFAULT_ENTITY_LABELS, DEFAULT_NATIVE_PIPELINE_CONFIG, DEFAULT_NATIVE_PIPELINE_WARMUPS, DETECTION_SOURCES, DETECTOR_PRIORITY, ENTITY_CAPABILITIES, ENTITY_LABELS, ENTITY_SELECTIONS, EXTERNAL_DETECTION_BATCH_MAX_BYTES, EXTERNAL_DETECTION_BATCH_VERSION, EXTERNAL_DETECTION_DOCUMENT_MAX_BYTES, EXTERNAL_DETECTION_MAX_DETECTIONS, EXTERNAL_DETECTION_MAX_LABEL_MAPPINGS, EXTERNAL_DETECTION_MAX_METADATA_BYTES, EXTERNAL_DETECTION_OFFSET_UNITS, EXTERNAL_DETECTION_PROVIDER_ID_MAX_BYTES, OPERATOR_TYPES, PreparedAnonymizer, PreparedNativeAnonymizer, PreparedNativePipeline, PreparedNativeRedactionSession, PreparedNativeSessionRedactionPlan, PreparedSearch, assertNativeBindingVersion, assertNativePipelineSupported, availableDefaultNativePipelineLanguages, available_default_native_pipeline_languages, convert_external_detection_batch, createNativeAnonymizerFromConfig, createNativeAnonymizerFromPackage, createNativePipelineFromConfig, createNativePipelineFromDefaultPackage, createNativePipelineFromPackage, createNativePipelineFromPackageFile, create_native_pipeline_from_default_package, deanonymise, diagnostics_json, diagnostics_stream_json, encodeNativeSearchConfig, encodeNativeSearchConfigInput, exportRedactionKey, getDefaultNativePipeline, getNativeBindingVersion, getNativePipelineCompatibility, get_default_native_pipeline, loadNativeAnonymizeBinding, load_prepared_package, load_prepared_package_file, native_package_version, normalize_for_search, preloadDefaultNativePipeline, preloadDefaultNativePipelineAsync, preload_default_native_pipeline, prepareNativePipelineConfig, prepareNativePipelinePackage, prepareNativeSearchPackage, prepare_search_package, readDefaultNativePipelinePackageFile, readDefaultNativePipelinePackageFileAsync, readNativePipelinePackageFile, readNativePipelinePackageFileAsync, read_default_native_pipeline_package_file, redactDefaultText, redactDefaultTextJson, redact_default_text, redact_default_text_json, redact_text, redact_text_json, redact_text_stream_json, setNativeBindingOverride, summary_diagnostics_json };
30
30
 
31
31
  //# sourceMappingURL=index.mjs.map