skein-cli 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +180 -0
  3. package/bin/skein.mjs +7 -0
  4. package/dist/adapters/aider/conv-reader.d.ts +7 -0
  5. package/dist/adapters/aider/conv-reader.js +203 -0
  6. package/dist/adapters/aider/conv-reader.js.map +1 -0
  7. package/dist/adapters/aider/index.d.ts +2 -0
  8. package/dist/adapters/aider/index.js +123 -0
  9. package/dist/adapters/aider/index.js.map +1 -0
  10. package/dist/adapters/base.d.ts +71 -0
  11. package/dist/adapters/base.js +38 -0
  12. package/dist/adapters/base.js.map +1 -0
  13. package/dist/adapters/claude-code/conv-reader.d.ts +2 -0
  14. package/dist/adapters/claude-code/conv-reader.js +155 -0
  15. package/dist/adapters/claude-code/conv-reader.js.map +1 -0
  16. package/dist/adapters/claude-code/index.d.ts +3 -0
  17. package/dist/adapters/claude-code/index.js +517 -0
  18. package/dist/adapters/claude-code/index.js.map +1 -0
  19. package/dist/adapters/claude-desktop/index.d.ts +2 -0
  20. package/dist/adapters/claude-desktop/index.js +95 -0
  21. package/dist/adapters/claude-desktop/index.js.map +1 -0
  22. package/dist/adapters/codex/index.d.ts +2 -0
  23. package/dist/adapters/codex/index.js +472 -0
  24. package/dist/adapters/codex/index.js.map +1 -0
  25. package/dist/adapters/cursor/index.d.ts +2 -0
  26. package/dist/adapters/cursor/index.js +255 -0
  27. package/dist/adapters/cursor/index.js.map +1 -0
  28. package/dist/adapters/opencode/conv-reader.d.ts +3 -0
  29. package/dist/adapters/opencode/conv-reader.js +190 -0
  30. package/dist/adapters/opencode/conv-reader.js.map +1 -0
  31. package/dist/adapters/opencode/index.d.ts +2 -0
  32. package/dist/adapters/opencode/index.js +349 -0
  33. package/dist/adapters/opencode/index.js.map +1 -0
  34. package/dist/adapters/registry.d.ts +4 -0
  35. package/dist/adapters/registry.js +26 -0
  36. package/dist/adapters/registry.js.map +1 -0
  37. package/dist/cli.d.ts +3 -0
  38. package/dist/cli.js +54 -0
  39. package/dist/cli.js.map +1 -0
  40. package/dist/commands/conv.d.ts +2 -0
  41. package/dist/commands/conv.js +261 -0
  42. package/dist/commands/conv.js.map +1 -0
  43. package/dist/commands/doctor.d.ts +2 -0
  44. package/dist/commands/doctor.js +85 -0
  45. package/dist/commands/doctor.js.map +1 -0
  46. package/dist/commands/init.d.ts +2 -0
  47. package/dist/commands/init.js +38 -0
  48. package/dist/commands/init.js.map +1 -0
  49. package/dist/commands/memory.d.ts +2 -0
  50. package/dist/commands/memory.js +197 -0
  51. package/dist/commands/memory.js.map +1 -0
  52. package/dist/commands/migrate.d.ts +2 -0
  53. package/dist/commands/migrate.js +102 -0
  54. package/dist/commands/migrate.js.map +1 -0
  55. package/dist/commands/profile.d.ts +2 -0
  56. package/dist/commands/profile.js +183 -0
  57. package/dist/commands/profile.js.map +1 -0
  58. package/dist/commands/redact.d.ts +2 -0
  59. package/dist/commands/redact.js +73 -0
  60. package/dist/commands/redact.js.map +1 -0
  61. package/dist/commands/trace.d.ts +2 -0
  62. package/dist/commands/trace.js +181 -0
  63. package/dist/commands/trace.js.map +1 -0
  64. package/dist/commands/view.d.ts +13 -0
  65. package/dist/commands/view.js +184 -0
  66. package/dist/commands/view.js.map +1 -0
  67. package/dist/commands/watch.d.ts +6 -0
  68. package/dist/commands/watch.js +61 -0
  69. package/dist/commands/watch.js.map +1 -0
  70. package/dist/commands/wrap.d.ts +2 -0
  71. package/dist/commands/wrap.js +131 -0
  72. package/dist/commands/wrap.js.map +1 -0
  73. package/dist/conv/chatgpt-import.d.ts +33 -0
  74. package/dist/conv/chatgpt-import.js +145 -0
  75. package/dist/conv/chatgpt-import.js.map +1 -0
  76. package/dist/conv/cursor.d.ts +12 -0
  77. package/dist/conv/cursor.js +55 -0
  78. package/dist/conv/cursor.js.map +1 -0
  79. package/dist/conv/export.d.ts +40 -0
  80. package/dist/conv/export.js +215 -0
  81. package/dist/conv/export.js.map +1 -0
  82. package/dist/conv/replay/aider.d.ts +24 -0
  83. package/dist/conv/replay/aider.js +56 -0
  84. package/dist/conv/replay/aider.js.map +1 -0
  85. package/dist/conv/replay/claude-code.d.ts +38 -0
  86. package/dist/conv/replay/claude-code.js +80 -0
  87. package/dist/conv/replay/claude-code.js.map +1 -0
  88. package/dist/conv/replay/context.d.ts +25 -0
  89. package/dist/conv/replay/context.js +63 -0
  90. package/dist/conv/replay/context.js.map +1 -0
  91. package/dist/conv/replay/index.d.ts +22 -0
  92. package/dist/conv/replay/index.js +84 -0
  93. package/dist/conv/replay/index.js.map +1 -0
  94. package/dist/conv/search.d.ts +67 -0
  95. package/dist/conv/search.js +379 -0
  96. package/dist/conv/search.js.map +1 -0
  97. package/dist/conv/sink.d.ts +26 -0
  98. package/dist/conv/sink.js +76 -0
  99. package/dist/conv/sink.js.map +1 -0
  100. package/dist/conv/sources/aider.d.ts +13 -0
  101. package/dist/conv/sources/aider.js +95 -0
  102. package/dist/conv/sources/aider.js.map +1 -0
  103. package/dist/conv/sources/claude-code.d.ts +13 -0
  104. package/dist/conv/sources/claude-code.js +189 -0
  105. package/dist/conv/sources/claude-code.js.map +1 -0
  106. package/dist/conv/sources/codex.d.ts +15 -0
  107. package/dist/conv/sources/codex.js +175 -0
  108. package/dist/conv/sources/codex.js.map +1 -0
  109. package/dist/conv/sources/opencode.d.ts +12 -0
  110. package/dist/conv/sources/opencode.js +92 -0
  111. package/dist/conv/sources/opencode.js.map +1 -0
  112. package/dist/conv/store.d.ts +10 -0
  113. package/dist/conv/store.js +75 -0
  114. package/dist/conv/store.js.map +1 -0
  115. package/dist/conv/title.d.ts +9 -0
  116. package/dist/conv/title.js +74 -0
  117. package/dist/conv/title.js.map +1 -0
  118. package/dist/conv/watcher.d.ts +28 -0
  119. package/dist/conv/watcher.js +75 -0
  120. package/dist/conv/watcher.js.map +1 -0
  121. package/dist/conv/zip.d.ts +11 -0
  122. package/dist/conv/zip.js +82 -0
  123. package/dist/conv/zip.js.map +1 -0
  124. package/dist/hf/client.d.ts +41 -0
  125. package/dist/hf/client.js +87 -0
  126. package/dist/hf/client.js.map +1 -0
  127. package/dist/index.d.ts +5 -0
  128. package/dist/index.js +6 -0
  129. package/dist/index.js.map +1 -0
  130. package/dist/ir/index.d.ts +24 -0
  131. package/dist/ir/index.js +23 -0
  132. package/dist/ir/index.js.map +1 -0
  133. package/dist/ir/profile.d.ts +55 -0
  134. package/dist/ir/profile.js +177 -0
  135. package/dist/ir/profile.js.map +1 -0
  136. package/dist/memory/index.d.ts +41 -0
  137. package/dist/memory/index.js +109 -0
  138. package/dist/memory/index.js.map +1 -0
  139. package/dist/memory/search.d.ts +24 -0
  140. package/dist/memory/search.js +114 -0
  141. package/dist/memory/search.js.map +1 -0
  142. package/dist/memory/sinks/claude-mem.d.ts +13 -0
  143. package/dist/memory/sinks/claude-mem.js +100 -0
  144. package/dist/memory/sinks/claude-mem.js.map +1 -0
  145. package/dist/memory/sinks/codex.d.ts +12 -0
  146. package/dist/memory/sinks/codex.js +82 -0
  147. package/dist/memory/sinks/codex.js.map +1 -0
  148. package/dist/memory/sinks/context.d.ts +21 -0
  149. package/dist/memory/sinks/context.js +42 -0
  150. package/dist/memory/sinks/context.js.map +1 -0
  151. package/dist/memory/sources/chatgpt.d.ts +22 -0
  152. package/dist/memory/sources/chatgpt.js +98 -0
  153. package/dist/memory/sources/chatgpt.js.map +1 -0
  154. package/dist/memory/sources/claude-mem.d.ts +8 -0
  155. package/dist/memory/sources/claude-mem.js +104 -0
  156. package/dist/memory/sources/claude-mem.js.map +1 -0
  157. package/dist/memory/sources/codex.d.ts +8 -0
  158. package/dist/memory/sources/codex.js +77 -0
  159. package/dist/memory/sources/codex.js.map +1 -0
  160. package/dist/memory/store.d.ts +19 -0
  161. package/dist/memory/store.js +82 -0
  162. package/dist/memory/store.js.map +1 -0
  163. package/dist/proxy/http.d.ts +21 -0
  164. package/dist/proxy/http.js +205 -0
  165. package/dist/proxy/http.js.map +1 -0
  166. package/dist/proxy/recorder.d.ts +35 -0
  167. package/dist/proxy/recorder.js +221 -0
  168. package/dist/proxy/recorder.js.map +1 -0
  169. package/dist/proxy/streaming.d.ts +33 -0
  170. package/dist/proxy/streaming.js +185 -0
  171. package/dist/proxy/streaming.js.map +1 -0
  172. package/dist/redactor/entropy.d.ts +29 -0
  173. package/dist/redactor/entropy.js +98 -0
  174. package/dist/redactor/entropy.js.map +1 -0
  175. package/dist/redactor/index.d.ts +52 -0
  176. package/dist/redactor/index.js +152 -0
  177. package/dist/redactor/index.js.map +1 -0
  178. package/dist/redactor/ner.d.ts +53 -0
  179. package/dist/redactor/ner.js +97 -0
  180. package/dist/redactor/ner.js.map +1 -0
  181. package/dist/redactor/pii-patterns.d.ts +22 -0
  182. package/dist/redactor/pii-patterns.js +187 -0
  183. package/dist/redactor/pii-patterns.js.map +1 -0
  184. package/dist/redactor/secret-patterns.d.ts +27 -0
  185. package/dist/redactor/secret-patterns.js +475 -0
  186. package/dist/redactor/secret-patterns.js.map +1 -0
  187. package/dist/schema/conv.d.ts +698 -0
  188. package/dist/schema/conv.js +85 -0
  189. package/dist/schema/conv.js.map +1 -0
  190. package/dist/schema/index.d.ts +2 -0
  191. package/dist/schema/index.js +3 -0
  192. package/dist/schema/index.js.map +1 -0
  193. package/dist/schema/manifest.d.ts +1531 -0
  194. package/dist/schema/manifest.js +179 -0
  195. package/dist/schema/manifest.js.map +1 -0
  196. package/dist/schema/memory.d.ts +107 -0
  197. package/dist/schema/memory.js +45 -0
  198. package/dist/schema/memory.js.map +1 -0
  199. package/dist/schema/trace.d.ts +164 -0
  200. package/dist/schema/trace.js +89 -0
  201. package/dist/schema/trace.js.map +1 -0
  202. package/dist/trace/consent.d.ts +30 -0
  203. package/dist/trace/consent.js +60 -0
  204. package/dist/trace/consent.js.map +1 -0
  205. package/dist/trace/extract.d.ts +22 -0
  206. package/dist/trace/extract.js +168 -0
  207. package/dist/trace/extract.js.map +1 -0
  208. package/dist/trace/ml-pii.d.ts +33 -0
  209. package/dist/trace/ml-pii.js +35 -0
  210. package/dist/trace/ml-pii.js.map +1 -0
  211. package/dist/trace/push.d.ts +59 -0
  212. package/dist/trace/push.js +141 -0
  213. package/dist/trace/push.js.map +1 -0
  214. package/dist/trace/serialize.d.ts +23 -0
  215. package/dist/trace/serialize.js +67 -0
  216. package/dist/trace/serialize.js.map +1 -0
  217. package/dist/ui/banner.d.ts +2 -0
  218. package/dist/ui/banner.js +17 -0
  219. package/dist/ui/banner.js.map +1 -0
  220. package/dist/ui/box.d.ts +4 -0
  221. package/dist/ui/box.js +38 -0
  222. package/dist/ui/box.js.map +1 -0
  223. package/dist/ui/index.d.ts +5 -0
  224. package/dist/ui/index.js +5 -0
  225. package/dist/ui/index.js.map +1 -0
  226. package/dist/ui/spinner.d.ts +10 -0
  227. package/dist/ui/spinner.js +44 -0
  228. package/dist/ui/spinner.js.map +1 -0
  229. package/dist/ui/table.d.ts +9 -0
  230. package/dist/ui/table.js +55 -0
  231. package/dist/ui/table.js.map +1 -0
  232. package/dist/util/frontmatter.d.ts +6 -0
  233. package/dist/util/frontmatter.js +20 -0
  234. package/dist/util/frontmatter.js.map +1 -0
  235. package/dist/util/fs.d.ts +5 -0
  236. package/dist/util/fs.js +41 -0
  237. package/dist/util/fs.js.map +1 -0
  238. package/dist/util/ids.d.ts +3 -0
  239. package/dist/util/ids.js +16 -0
  240. package/dist/util/ids.js.map +1 -0
  241. package/dist/util/log.d.ts +13 -0
  242. package/dist/util/log.js +33 -0
  243. package/dist/util/log.js.map +1 -0
  244. package/dist/util/paths.d.ts +18 -0
  245. package/dist/util/paths.js +36 -0
  246. package/dist/util/paths.js.map +1 -0
  247. package/dist/version.d.ts +5 -0
  248. package/dist/version.js +32 -0
  249. package/dist/version.js.map +1 -0
  250. package/package.json +86 -0
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Optional ML-based PII detection via Transformers.js.
3
+ *
4
+ * Default model: `iiiorg/piiranha-v1-detect-personal-information` —
5
+ * a DeBERTa-v3 fine-tune released by Inferentia Internet Investigation
6
+ * that detects 17 PII categories and works well on English text. The
7
+ * model is lazy-loaded and cached in ~/.cache/huggingface/.
8
+ *
9
+ * `@huggingface/transformers` is declared as an OPTIONAL dependency.
10
+ * If onnxruntime-node fails to install (e.g. unsupported platform),
11
+ * the rest of Skein keeps working — calls to `nerPiiAnalyze` just
12
+ * return an empty hit list and the orchestrator logs a one-time
13
+ * notice.
14
+ *
15
+ * Set SKEIN_PII_MODEL to override the default.
16
+ */
17
+ export const DEFAULT_NER_MODEL = process.env['SKEIN_PII_MODEL'] ?? 'iiiorg/piiranha-v1-detect-personal-information';
18
+ let cachedPipeline;
19
+ let unavailableReason;
20
+ /**
21
+ * Initialize the NER pipeline. Returns undefined if @huggingface/transformers
22
+ * is not installed or the model fails to load. Logs the reason exactly once.
23
+ */
24
+ export async function loadNerPipeline() {
25
+ if (cachedPipeline)
26
+ return cachedPipeline;
27
+ if (unavailableReason)
28
+ return undefined;
29
+ try {
30
+ const transformers = (await import(
31
+ /* webpackIgnore: true */ /* @vite-ignore */ '@huggingface/transformers'));
32
+ cachedPipeline = await transformers.pipeline('token-classification', DEFAULT_NER_MODEL, {
33
+ aggregation_strategy: 'simple',
34
+ });
35
+ return cachedPipeline;
36
+ }
37
+ catch (err) {
38
+ unavailableReason = err.message;
39
+ return undefined;
40
+ }
41
+ }
42
+ /**
43
+ * Run the configured PII NER over `input`. Returns hits with the
44
+ * model's score (0..1). Score threshold defaults to 0.5.
45
+ */
46
+ export async function nerPiiAnalyze(input, minScore = 0.5) {
47
+ const pipeline = await loadNerPipeline();
48
+ if (!pipeline)
49
+ return [];
50
+ if (!input.trim())
51
+ return [];
52
+ const raw = await pipeline(input);
53
+ const hits = [];
54
+ for (const item of raw) {
55
+ if (item.score < minScore)
56
+ continue;
57
+ const category = item.entity_group ?? item.entity ?? 'PII';
58
+ if (category === 'O')
59
+ continue;
60
+ hits.push({
61
+ category,
62
+ start: item.start,
63
+ end: item.end,
64
+ match: item.word,
65
+ score: item.score,
66
+ });
67
+ }
68
+ return hits;
69
+ }
70
+ export function lastNerError() {
71
+ return unavailableReason;
72
+ }
73
+ /**
74
+ * Replace NER hits in the input with `[REDACTED:<category>]`.
75
+ */
76
+ export function redactNer(input, hits) {
77
+ if (hits.length === 0)
78
+ return { text: input, hits: [] };
79
+ const ordered = [...hits].sort((a, b) => a.start - b.start);
80
+ const merged = [];
81
+ for (const hit of ordered) {
82
+ const prev = merged[merged.length - 1];
83
+ if (prev && hit.start < prev.end)
84
+ continue;
85
+ merged.push(hit);
86
+ }
87
+ let cursor = 0;
88
+ const parts = [];
89
+ for (const hit of merged) {
90
+ parts.push(input.slice(cursor, hit.start));
91
+ parts.push(`[REDACTED:${hit.category.toLowerCase()}]`);
92
+ cursor = hit.end;
93
+ }
94
+ parts.push(input.slice(cursor));
95
+ return { text: parts.join(''), hits: merged };
96
+ }
97
+ //# sourceMappingURL=ner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ner.js","sourceRoot":"","sources":["../../src/redactor/ner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Personally Identifiable Information patterns. Structured PII first
3
+ * (email, CC, SSN) and progressively less precise patterns after.
4
+ *
5
+ * Credit cards run a Luhn check to keep false positives low.
6
+ */
7
+ export type PiiCategory = 'email' | 'phone' | 'credit-card' | 'ssn-us' | 'iban' | 'ipv4' | 'ipv6' | 'mac' | 'date-of-birth' | 'address-us' | 'driver-license-us';
8
+ export interface PiiHit {
9
+ category: PiiCategory;
10
+ start: number;
11
+ end: number;
12
+ match: string;
13
+ /** Optional rationale: why we matched (e.g. "Luhn passed"). */
14
+ rationale?: string;
15
+ }
16
+ export declare const PII_REPLACEMENTS: Record<PiiCategory, string>;
17
+ export declare function findPiiHits(input: string): PiiHit[];
18
+ export declare function redactPii(input: string): {
19
+ text: string;
20
+ hits: PiiHit[];
21
+ };
22
+ export declare function luhn(digits: string): boolean;
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Personally Identifiable Information patterns. Structured PII first
3
+ * (email, CC, SSN) and progressively less precise patterns after.
4
+ *
5
+ * Credit cards run a Luhn check to keep false positives low.
6
+ */
7
+ const EMAIL_REGEX = /\b[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,253}\.[A-Za-z]{2,24}\b/g;
8
+ // E.164 plus common US / international shapes. Validates 7–15 digits via
9
+ // the digit count check in collectPhones — the regex is intentionally
10
+ // permissive about grouping.
11
+ const PHONE_REGEX = /(?<!\d)(?:\+\d{1,3}[\s.-]?)?(?:\(\d{1,4}\)|\d{1,4})(?:[\s.-]?\d{1,4}){1,5}(?!\d)/g;
12
+ const CC_CANDIDATE_REGEX = /\b(?:\d[ -]?){13,19}\b/g;
13
+ const SSN_US_REGEX = /\b(?!000|666|9\d{2})\d{3}-(?!00)\d{2}-(?!0000)\d{4}\b/g;
14
+ const IBAN_REGEX = /\b[A-Z]{2}\d{2}(?:[ ]?[A-Z0-9]{4}){2,7}(?:[ ]?[A-Z0-9]{1,4})?\b/g;
15
+ const IPV4_REGEX = /\b(?:25[0-5]|2[0-4]\d|[01]?\d\d?)(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}\b/g;
16
+ const IPV6_REGEX = /\b(?:[A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}\b/g;
17
+ const MAC_REGEX = /\b(?:[A-Fa-f0-9]{2}[:-]){5}[A-Fa-f0-9]{2}\b/g;
18
+ const DOB_REGEX = /\b(?:(?:0?[1-9]|1[0-2])[/-](?:0?[1-9]|[12]\d|3[01])[/-](?:19|20)\d{2}|(?:19|20)\d{2}-(?:0?[1-9]|1[0-2])-(?:0?[1-9]|[12]\d|3[01]))\b/g;
19
+ const ADDRESS_US_REGEX = /\b\d{1,5}\s+(?:[A-Z][a-z]+\s){0,2}(?:Street|St\.?|Avenue|Ave\.?|Road|Rd\.?|Boulevard|Blvd\.?|Drive|Dr\.?|Lane|Ln\.?|Court|Ct\.?|Way|Place|Pl\.?|Highway|Hwy\.?|Square|Sq\.?)\b/g;
20
+ const DL_US_REGEX = /\b[A-Z]\d{7,8}\b(?=[^\d]*(?:driver|license|dl|driver's))/gi;
21
+ export const PII_REPLACEMENTS = {
22
+ email: '[REDACTED:email]',
23
+ phone: '[REDACTED:phone]',
24
+ 'credit-card': '[REDACTED:credit-card]',
25
+ 'ssn-us': '[REDACTED:ssn]',
26
+ iban: '[REDACTED:iban]',
27
+ ipv4: '[REDACTED:ipv4]',
28
+ ipv6: '[REDACTED:ipv6]',
29
+ mac: '[REDACTED:mac]',
30
+ 'date-of-birth': '[REDACTED:dob]',
31
+ 'address-us': '[REDACTED:address]',
32
+ 'driver-license-us': '[REDACTED:driver-license]',
33
+ };
34
+ export function findPiiHits(input) {
35
+ const hits = [];
36
+ // High-confidence patterns first; mergeNonOverlapping is stable so earlier
37
+ // additions win on ties.
38
+ collectMatches(EMAIL_REGEX, 'email', input, hits);
39
+ collectMatches(SSN_US_REGEX, 'ssn-us', input, hits);
40
+ collectMatches(IBAN_REGEX, 'iban', input, hits);
41
+ collectMatches(IPV6_REGEX, 'ipv6', input, hits);
42
+ collectMatches(IPV4_REGEX, 'ipv4', input, hits);
43
+ collectMatches(MAC_REGEX, 'mac', input, hits);
44
+ collectCreditCards(input, hits);
45
+ collectDateOfBirth(input, hits);
46
+ collectMatches(ADDRESS_US_REGEX, 'address-us', input, hits);
47
+ collectMatches(DL_US_REGEX, 'driver-license-us', input, hits);
48
+ collectPhones(input, hits);
49
+ return mergeNonOverlapping(hits);
50
+ }
51
+ export function redactPii(input) {
52
+ const hits = findPiiHits(input);
53
+ if (hits.length === 0)
54
+ return { text: input, hits: [] };
55
+ const ordered = [...hits].sort((a, b) => a.start - b.start);
56
+ let cursor = 0;
57
+ const parts = [];
58
+ for (const hit of ordered) {
59
+ parts.push(input.slice(cursor, hit.start));
60
+ parts.push(PII_REPLACEMENTS[hit.category]);
61
+ cursor = hit.end;
62
+ }
63
+ parts.push(input.slice(cursor));
64
+ return { text: parts.join(''), hits: ordered };
65
+ }
66
+ function collectMatches(regex, category, input, out) {
67
+ regex.lastIndex = 0;
68
+ let match;
69
+ while ((match = regex.exec(input))) {
70
+ out.push({
71
+ category,
72
+ start: match.index,
73
+ end: match.index + match[0].length,
74
+ match: match[0],
75
+ });
76
+ }
77
+ }
78
+ function collectPhones(input, out) {
79
+ PHONE_REGEX.lastIndex = 0;
80
+ let match;
81
+ while ((match = PHONE_REGEX.exec(input))) {
82
+ const raw = match[0];
83
+ if (looksLikeDateOrTimestamp(raw))
84
+ continue;
85
+ const digits = raw.replace(/\D/g, '');
86
+ if (digits.length < 7 || digits.length > 15)
87
+ continue;
88
+ // Require any of: + prefix, parentheses, or ≥ 10 digits — without one of
89
+ // these signals it's far more likely to be an id, a price, a date, or a
90
+ // version number than a real phone.
91
+ if (!raw.includes('+') && !raw.includes('(') && digits.length < 10)
92
+ continue;
93
+ out.push({
94
+ category: 'phone',
95
+ start: match.index,
96
+ end: match.index + raw.length,
97
+ match: raw,
98
+ });
99
+ }
100
+ }
101
+ // Skip strings that match common date / timestamp shapes — they overlap with
102
+ // permissive phone patterns and create noisy false positives in transcripts.
103
+ const ISO_DATE_PREFIX = /^\d{4}-\d{2}-\d{2}/;
104
+ const SLASH_DATE = /^\d{1,4}\/\d{1,2}\/\d{1,4}$/;
105
+ const DOT_DATE = /^\d{1,4}\.\d{1,2}\.\d{1,4}$/;
106
+ function looksLikeDateOrTimestamp(raw) {
107
+ if (ISO_DATE_PREFIX.test(raw))
108
+ return true;
109
+ if (SLASH_DATE.test(raw))
110
+ return true;
111
+ if (DOT_DATE.test(raw))
112
+ return true;
113
+ return false;
114
+ }
115
+ const DOB_CONTEXT = /\b(?:dob|d\.o\.b|born|birth ?date|date of birth|birthday|birthdate)\b/i;
116
+ // DOB shapes overlap with garden-variety timestamps (`2026-06-14`,
117
+ // `2024/06/14`, `14/06/2024`), so only mark a date as a DOB when a
118
+ // birth-context keyword appears nearby. Without the keyword we leave the
119
+ // date alone and let the rest of the pipeline make the call.
120
+ function collectDateOfBirth(input, out) {
121
+ DOB_REGEX.lastIndex = 0;
122
+ let match;
123
+ while ((match = DOB_REGEX.exec(input))) {
124
+ const start = match.index;
125
+ const raw = match[0];
126
+ const windowStart = Math.max(0, start - 48);
127
+ const window = input.slice(windowStart, start);
128
+ if (!DOB_CONTEXT.test(window))
129
+ continue;
130
+ out.push({
131
+ category: 'date-of-birth',
132
+ start,
133
+ end: start + raw.length,
134
+ match: raw,
135
+ rationale: 'DOB context keyword nearby',
136
+ });
137
+ }
138
+ }
139
+ function collectCreditCards(input, out) {
140
+ CC_CANDIDATE_REGEX.lastIndex = 0;
141
+ let match;
142
+ while ((match = CC_CANDIDATE_REGEX.exec(input))) {
143
+ const raw = match[0];
144
+ const digits = raw.replace(/[\s-]/g, '');
145
+ if (digits.length < 13 || digits.length > 19)
146
+ continue;
147
+ if (!luhn(digits))
148
+ continue;
149
+ out.push({
150
+ category: 'credit-card',
151
+ start: match.index,
152
+ end: match.index + raw.length,
153
+ match: raw,
154
+ rationale: 'Luhn passed',
155
+ });
156
+ }
157
+ }
158
+ export function luhn(digits) {
159
+ let sum = 0;
160
+ let shouldDouble = false;
161
+ for (let i = digits.length - 1; i >= 0; i--) {
162
+ const code = digits.charCodeAt(i) - 48;
163
+ if (code < 0 || code > 9)
164
+ return false;
165
+ let n = code;
166
+ if (shouldDouble) {
167
+ n *= 2;
168
+ if (n > 9)
169
+ n -= 9;
170
+ }
171
+ sum += n;
172
+ shouldDouble = !shouldDouble;
173
+ }
174
+ return sum % 10 === 0;
175
+ }
176
+ function mergeNonOverlapping(hits) {
177
+ const sorted = [...hits].sort((a, b) => a.start - b.start);
178
+ const result = [];
179
+ for (const hit of sorted) {
180
+ const prev = result[result.length - 1];
181
+ if (prev && hit.start < prev.end)
182
+ continue;
183
+ result.push(hit);
184
+ }
185
+ return result;
186
+ }
187
+ //# sourceMappingURL=pii-patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pii-patterns.js","sourceRoot":"","sources":["../../src/redactor/pii-patterns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Comprehensive secret patterns curated from Gitleaks, TruffleHog, and
3
+ * detect-secrets rule sets, then narrowed to the patterns most relevant
4
+ * to AI coding tool transcripts.
5
+ *
6
+ * Each pattern has:
7
+ * - id: stable identifier surfaced in redaction reports
8
+ * - category: groups patterns for opt-in/opt-out
9
+ * - name: human-readable label
10
+ * - regex: detection pattern (must use `g` flag)
11
+ * - replacement: token written in place of the match
12
+ * - severity: high (real credential), medium (likely credential), low (heuristic)
13
+ *
14
+ * Replacements use [REDACTED:<id>] so reviewers can grep for what was lost.
15
+ */
16
+ export type Severity = 'high' | 'medium' | 'low';
17
+ export type Category = 'llm-provider' | 'cloud' | 'scm' | 'payment' | 'comms' | 'database' | 'package' | 'monitoring' | 'productivity' | 'generic';
18
+ export interface SecretPattern {
19
+ id: string;
20
+ category: Category;
21
+ name: string;
22
+ regex: RegExp;
23
+ replacement: string;
24
+ severity: Severity;
25
+ }
26
+ export declare const SECRET_PATTERNS: SecretPattern[];
27
+ export declare function patternsByCategory(...categories: Category[]): SecretPattern[];