@mrciphersmith/keryx 0.3.19 → 0.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +73 -17
- package/dist/core.js +72 -16
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -9091,8 +9091,24 @@ function lastLineOf(before) {
|
|
|
9091
9091
|
`);
|
|
9092
9092
|
return newline < 0 ? before : before.slice(newline + 1);
|
|
9093
9093
|
}
|
|
9094
|
+
function isPlainCasedWord(letters) {
|
|
9095
|
+
return /^[a-z]+$/.test(letters) || /^[A-Z]+$/.test(letters) || /^[A-Z][a-z]*$/.test(letters);
|
|
9096
|
+
}
|
|
9094
9097
|
function isSingleTransitionTag(segment) {
|
|
9095
|
-
|
|
9098
|
+
const letterThenDigit = /^([A-Za-z]+)([0-9]+)$/.exec(segment);
|
|
9099
|
+
if (letterThenDigit !== null) {
|
|
9100
|
+
const letters = letterThenDigit[1];
|
|
9101
|
+
return letters.length <= TAG_MAX_LETTER_RUN && isPlainCasedWord(letters);
|
|
9102
|
+
}
|
|
9103
|
+
const digitThenLetter = /^([0-9]+)([A-Za-z]+)$/.exec(segment);
|
|
9104
|
+
if (digitThenLetter !== null) {
|
|
9105
|
+
const letters = digitThenLetter[2];
|
|
9106
|
+
return letters.length <= TAG_MAX_LETTER_RUN && isPlainCasedWord(letters);
|
|
9107
|
+
}
|
|
9108
|
+
return false;
|
|
9109
|
+
}
|
|
9110
|
+
function isSlugHexTail(segment) {
|
|
9111
|
+
return SLUG_HEX_TAIL_RE.test(segment);
|
|
9096
9112
|
}
|
|
9097
9113
|
function isWordSlug(value) {
|
|
9098
9114
|
const segments = value.split(/[-_]/);
|
|
@@ -9100,15 +9116,25 @@ function isWordSlug(value) {
|
|
|
9100
9116
|
return false;
|
|
9101
9117
|
}
|
|
9102
9118
|
let words = 0;
|
|
9103
|
-
for (
|
|
9104
|
-
const
|
|
9119
|
+
for (let i = 0;i < segments.length; i += 1) {
|
|
9120
|
+
const segment = segments[i];
|
|
9105
9121
|
const isDigits = /^[0-9]+$/.test(segment);
|
|
9106
|
-
if (
|
|
9107
|
-
|
|
9122
|
+
if (isDigits) {
|
|
9123
|
+
continue;
|
|
9108
9124
|
}
|
|
9109
|
-
if (
|
|
9110
|
-
|
|
9125
|
+
if (isPlainCasedWord(segment)) {
|
|
9126
|
+
if (segment.length >= 3) {
|
|
9127
|
+
words += 1;
|
|
9128
|
+
}
|
|
9129
|
+
continue;
|
|
9130
|
+
}
|
|
9131
|
+
if (isSingleTransitionTag(segment)) {
|
|
9132
|
+
continue;
|
|
9133
|
+
}
|
|
9134
|
+
if (i === segments.length - 1 && isSlugHexTail(segment)) {
|
|
9135
|
+
continue;
|
|
9111
9136
|
}
|
|
9137
|
+
return false;
|
|
9112
9138
|
}
|
|
9113
9139
|
return words >= 1;
|
|
9114
9140
|
}
|
|
@@ -9252,6 +9278,29 @@ function secretShapedCandidatesIn(text) {
|
|
|
9252
9278
|
function looksSecretShapedIn(text) {
|
|
9253
9279
|
return secretShapedCandidatesIn(text).length > 0;
|
|
9254
9280
|
}
|
|
9281
|
+
function labelledPieceQualifies(piece) {
|
|
9282
|
+
const base = bareShapeQualifies(piece);
|
|
9283
|
+
if (base.qualifies) {
|
|
9284
|
+
return { entropy: base.entropy };
|
|
9285
|
+
}
|
|
9286
|
+
if (isAllowShapedValue(piece)) {
|
|
9287
|
+
return { entropy: base.entropy };
|
|
9288
|
+
}
|
|
9289
|
+
return null;
|
|
9290
|
+
}
|
|
9291
|
+
function firstQualifyingSlashPiece(head) {
|
|
9292
|
+
let offset = 0;
|
|
9293
|
+
for (const piece of head.split("/")) {
|
|
9294
|
+
if (piece.length > 0) {
|
|
9295
|
+
const found = labelledPieceQualifies(piece);
|
|
9296
|
+
if (found !== null) {
|
|
9297
|
+
return { offset, length: piece.length, entropy: found.entropy };
|
|
9298
|
+
}
|
|
9299
|
+
}
|
|
9300
|
+
offset += piece.length + 1;
|
|
9301
|
+
}
|
|
9302
|
+
return null;
|
|
9303
|
+
}
|
|
9255
9304
|
function detectEntropy(content) {
|
|
9256
9305
|
const matches = [];
|
|
9257
9306
|
const urlSpans = findUrlSpans(content);
|
|
@@ -9291,25 +9340,31 @@ function detectEntropy(content) {
|
|
|
9291
9340
|
if (matches.some((existing) => start < existing.end && end > existing.start)) {
|
|
9292
9341
|
continue;
|
|
9293
9342
|
}
|
|
9294
|
-
const
|
|
9295
|
-
|
|
9296
|
-
if (!qualifies) {
|
|
9343
|
+
const before = lastLineOf(content.slice(Math.max(0, start - LABEL_WINDOW), start));
|
|
9344
|
+
if (!ADJACENT_LABEL.test(before)) {
|
|
9297
9345
|
continue;
|
|
9298
9346
|
}
|
|
9299
|
-
const
|
|
9300
|
-
if (
|
|
9347
|
+
const head = TOKEN_HEAD.exec(value)?.[0] ?? value;
|
|
9348
|
+
if (head.includes("/")) {
|
|
9349
|
+
const piece = firstQualifyingSlashPiece(head);
|
|
9350
|
+
if (piece === null) {
|
|
9351
|
+
continue;
|
|
9352
|
+
}
|
|
9353
|
+
const pieceStart = start + piece.offset;
|
|
9354
|
+
const pieceEnd = pieceStart + piece.length;
|
|
9355
|
+
matches.push(buildMatch(pieceStart, pieceEnd, content.slice(pieceStart, pieceEnd), piece.entropy));
|
|
9301
9356
|
continue;
|
|
9302
9357
|
}
|
|
9303
|
-
|
|
9358
|
+
const found = labelledPieceQualifies(head);
|
|
9359
|
+
if (found === null) {
|
|
9304
9360
|
continue;
|
|
9305
9361
|
}
|
|
9306
|
-
matches.push(buildMatch(start, end, value, entropy));
|
|
9362
|
+
matches.push(buildMatch(start, end, value, found.entropy));
|
|
9307
9363
|
}
|
|
9308
9364
|
return matches.sort((a, b) => a.start - b.start);
|
|
9309
9365
|
}
|
|
9310
|
-
var SENSITIVE_LABEL_WORDS = "key|secret|token|password|passwd|api|credential|auth|bearer", caseless = (words) => words.replace(/[a-z]/g, (ch) => `[${ch}${ch.toUpperCase()}]`),
|
|
9366
|
+
var SENSITIVE_LABEL_WORDS = "key|secret|token|password|passwd|api|credential|auth|bearer", caseless = (words) => words.replace(/[a-z]/g, (ch) => `[${ch}${ch.toUpperCase()}]`), ADJACENT_LABEL, LABEL_ASSIGNMENT_RE, TOKEN, TOKEN_HEAD, LABEL_WINDOW = 40, HEX_BLOB, FULL_GIT_SHA_RE, UUID_RE, INTEGRITY_RE, TAG_MAX_LETTER_RUN = 8, SLUG_HEX_TAIL_RE, URL_SPAN_RE, URL_TRAILING_PUNCTUATION_RE, URL_COMPONENT_MIN_LENGTH = 20;
|
|
9311
9367
|
var init_entropy = __esm(() => {
|
|
9312
|
-
SENSITIVE_LABEL = new RegExp(`(?:^|[^A-Za-z0-9])(${caseless(SENSITIVE_LABEL_WORDS)})(?:$|[^A-Za-z0-9]|(?=[A-Z]))`);
|
|
9313
9368
|
ADJACENT_LABEL = new RegExp(`(?:^|[^A-Za-z0-9])(?:${caseless(SENSITIVE_LABEL_WORDS)})[A-Za-z0-9_-]*["']?\\s*[:=]?\\s*["']?$`);
|
|
9314
9369
|
LABEL_ASSIGNMENT_RE = new RegExp(`(?:^|[^A-Za-z0-9])(?:${SENSITIVE_LABEL_WORDS})[A-Za-z0-9_-]*"?\\s*=\\s*"?([A-Za-z0-9+/_=-]{6,})`, "gi");
|
|
9315
9370
|
TOKEN = /[A-Za-z0-9+/=_-]{20,}(?:\.[A-Za-z0-9+/=_-]{6,})*/g;
|
|
@@ -9318,6 +9373,7 @@ var init_entropy = __esm(() => {
|
|
|
9318
9373
|
FULL_GIT_SHA_RE = /^[0-9a-f]{40}$/i;
|
|
9319
9374
|
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
9320
9375
|
INTEGRITY_RE = /^(?:sha256|sha512)-[A-Za-z0-9+/]+=*$/;
|
|
9376
|
+
SLUG_HEX_TAIL_RE = /^[0-9a-f]{10,16}$/i;
|
|
9321
9377
|
URL_SPAN_RE = /\bhttps?:\/\/[^\s<>"'\\]+/g;
|
|
9322
9378
|
URL_TRAILING_PUNCTUATION_RE = /[.,;:!?)\]}]$/;
|
|
9323
9379
|
});
|
|
@@ -18037,7 +18093,7 @@ var package_default;
|
|
|
18037
18093
|
var init_package = __esm(() => {
|
|
18038
18094
|
package_default = {
|
|
18039
18095
|
name: "@mrciphersmith/keryx",
|
|
18040
|
-
version: "0.3.
|
|
18096
|
+
version: "0.3.20",
|
|
18041
18097
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
18042
18098
|
private: false,
|
|
18043
18099
|
publishConfig: {
|
package/dist/core.js
CHANGED
|
@@ -4040,8 +4040,24 @@ function lastLineOf(before) {
|
|
|
4040
4040
|
`);
|
|
4041
4041
|
return newline < 0 ? before : before.slice(newline + 1);
|
|
4042
4042
|
}
|
|
4043
|
+
function isPlainCasedWord(letters) {
|
|
4044
|
+
return /^[a-z]+$/.test(letters) || /^[A-Z]+$/.test(letters) || /^[A-Z][a-z]*$/.test(letters);
|
|
4045
|
+
}
|
|
4043
4046
|
function isSingleTransitionTag(segment) {
|
|
4044
|
-
|
|
4047
|
+
const letterThenDigit = /^([A-Za-z]+)([0-9]+)$/.exec(segment);
|
|
4048
|
+
if (letterThenDigit !== null) {
|
|
4049
|
+
const letters = letterThenDigit[1];
|
|
4050
|
+
return letters.length <= TAG_MAX_LETTER_RUN && isPlainCasedWord(letters);
|
|
4051
|
+
}
|
|
4052
|
+
const digitThenLetter = /^([0-9]+)([A-Za-z]+)$/.exec(segment);
|
|
4053
|
+
if (digitThenLetter !== null) {
|
|
4054
|
+
const letters = digitThenLetter[2];
|
|
4055
|
+
return letters.length <= TAG_MAX_LETTER_RUN && isPlainCasedWord(letters);
|
|
4056
|
+
}
|
|
4057
|
+
return false;
|
|
4058
|
+
}
|
|
4059
|
+
function isSlugHexTail(segment) {
|
|
4060
|
+
return SLUG_HEX_TAIL_RE.test(segment);
|
|
4045
4061
|
}
|
|
4046
4062
|
function isWordSlug(value) {
|
|
4047
4063
|
const segments = value.split(/[-_]/);
|
|
@@ -4049,15 +4065,25 @@ function isWordSlug(value) {
|
|
|
4049
4065
|
return false;
|
|
4050
4066
|
}
|
|
4051
4067
|
let words = 0;
|
|
4052
|
-
for (
|
|
4053
|
-
const
|
|
4068
|
+
for (let i = 0;i < segments.length; i += 1) {
|
|
4069
|
+
const segment = segments[i];
|
|
4054
4070
|
const isDigits = /^[0-9]+$/.test(segment);
|
|
4055
|
-
if (
|
|
4056
|
-
|
|
4071
|
+
if (isDigits) {
|
|
4072
|
+
continue;
|
|
4057
4073
|
}
|
|
4058
|
-
if (
|
|
4059
|
-
|
|
4074
|
+
if (isPlainCasedWord(segment)) {
|
|
4075
|
+
if (segment.length >= 3) {
|
|
4076
|
+
words += 1;
|
|
4077
|
+
}
|
|
4078
|
+
continue;
|
|
4079
|
+
}
|
|
4080
|
+
if (isSingleTransitionTag(segment)) {
|
|
4081
|
+
continue;
|
|
4060
4082
|
}
|
|
4083
|
+
if (i === segments.length - 1 && isSlugHexTail(segment)) {
|
|
4084
|
+
continue;
|
|
4085
|
+
}
|
|
4086
|
+
return false;
|
|
4061
4087
|
}
|
|
4062
4088
|
return words >= 1;
|
|
4063
4089
|
}
|
|
@@ -4201,6 +4227,29 @@ function secretShapedCandidatesIn(text) {
|
|
|
4201
4227
|
function looksSecretShapedIn(text) {
|
|
4202
4228
|
return secretShapedCandidatesIn(text).length > 0;
|
|
4203
4229
|
}
|
|
4230
|
+
function labelledPieceQualifies(piece) {
|
|
4231
|
+
const base = bareShapeQualifies(piece);
|
|
4232
|
+
if (base.qualifies) {
|
|
4233
|
+
return { entropy: base.entropy };
|
|
4234
|
+
}
|
|
4235
|
+
if (isAllowShapedValue(piece)) {
|
|
4236
|
+
return { entropy: base.entropy };
|
|
4237
|
+
}
|
|
4238
|
+
return null;
|
|
4239
|
+
}
|
|
4240
|
+
function firstQualifyingSlashPiece(head) {
|
|
4241
|
+
let offset = 0;
|
|
4242
|
+
for (const piece of head.split("/")) {
|
|
4243
|
+
if (piece.length > 0) {
|
|
4244
|
+
const found = labelledPieceQualifies(piece);
|
|
4245
|
+
if (found !== null) {
|
|
4246
|
+
return { offset, length: piece.length, entropy: found.entropy };
|
|
4247
|
+
}
|
|
4248
|
+
}
|
|
4249
|
+
offset += piece.length + 1;
|
|
4250
|
+
}
|
|
4251
|
+
return null;
|
|
4252
|
+
}
|
|
4204
4253
|
function detectEntropy(content) {
|
|
4205
4254
|
const matches = [];
|
|
4206
4255
|
const urlSpans = findUrlSpans(content);
|
|
@@ -4240,25 +4289,31 @@ function detectEntropy(content) {
|
|
|
4240
4289
|
if (matches.some((existing) => start < existing.end && end > existing.start)) {
|
|
4241
4290
|
continue;
|
|
4242
4291
|
}
|
|
4243
|
-
const
|
|
4244
|
-
|
|
4245
|
-
if (!qualifies) {
|
|
4292
|
+
const before = lastLineOf(content.slice(Math.max(0, start - LABEL_WINDOW), start));
|
|
4293
|
+
if (!ADJACENT_LABEL.test(before)) {
|
|
4246
4294
|
continue;
|
|
4247
4295
|
}
|
|
4248
|
-
const
|
|
4249
|
-
if (
|
|
4296
|
+
const head = TOKEN_HEAD.exec(value)?.[0] ?? value;
|
|
4297
|
+
if (head.includes("/")) {
|
|
4298
|
+
const piece = firstQualifyingSlashPiece(head);
|
|
4299
|
+
if (piece === null) {
|
|
4300
|
+
continue;
|
|
4301
|
+
}
|
|
4302
|
+
const pieceStart = start + piece.offset;
|
|
4303
|
+
const pieceEnd = pieceStart + piece.length;
|
|
4304
|
+
matches.push(buildMatch(pieceStart, pieceEnd, content.slice(pieceStart, pieceEnd), piece.entropy));
|
|
4250
4305
|
continue;
|
|
4251
4306
|
}
|
|
4252
|
-
|
|
4307
|
+
const found = labelledPieceQualifies(head);
|
|
4308
|
+
if (found === null) {
|
|
4253
4309
|
continue;
|
|
4254
4310
|
}
|
|
4255
|
-
matches.push(buildMatch(start, end, value, entropy));
|
|
4311
|
+
matches.push(buildMatch(start, end, value, found.entropy));
|
|
4256
4312
|
}
|
|
4257
4313
|
return matches.sort((a, b) => a.start - b.start);
|
|
4258
4314
|
}
|
|
4259
|
-
var SENSITIVE_LABEL_WORDS = "key|secret|token|password|passwd|api|credential|auth|bearer", caseless = (words) => words.replace(/[a-z]/g, (ch) => `[${ch}${ch.toUpperCase()}]`),
|
|
4315
|
+
var SENSITIVE_LABEL_WORDS = "key|secret|token|password|passwd|api|credential|auth|bearer", caseless = (words) => words.replace(/[a-z]/g, (ch) => `[${ch}${ch.toUpperCase()}]`), ADJACENT_LABEL, LABEL_ASSIGNMENT_RE, TOKEN, TOKEN_HEAD, LABEL_WINDOW = 40, HEX_BLOB, FULL_GIT_SHA_RE, UUID_RE, INTEGRITY_RE, TAG_MAX_LETTER_RUN = 8, SLUG_HEX_TAIL_RE, URL_SPAN_RE, URL_TRAILING_PUNCTUATION_RE, URL_COMPONENT_MIN_LENGTH = 20;
|
|
4260
4316
|
var init_entropy = __esm(() => {
|
|
4261
|
-
SENSITIVE_LABEL = new RegExp(`(?:^|[^A-Za-z0-9])(${caseless(SENSITIVE_LABEL_WORDS)})(?:$|[^A-Za-z0-9]|(?=[A-Z]))`);
|
|
4262
4317
|
ADJACENT_LABEL = new RegExp(`(?:^|[^A-Za-z0-9])(?:${caseless(SENSITIVE_LABEL_WORDS)})[A-Za-z0-9_-]*["']?\\s*[:=]?\\s*["']?$`);
|
|
4263
4318
|
LABEL_ASSIGNMENT_RE = new RegExp(`(?:^|[^A-Za-z0-9])(?:${SENSITIVE_LABEL_WORDS})[A-Za-z0-9_-]*"?\\s*=\\s*"?([A-Za-z0-9+/_=-]{6,})`, "gi");
|
|
4264
4319
|
TOKEN = /[A-Za-z0-9+/=_-]{20,}(?:\.[A-Za-z0-9+/=_-]{6,})*/g;
|
|
@@ -4267,6 +4322,7 @@ var init_entropy = __esm(() => {
|
|
|
4267
4322
|
FULL_GIT_SHA_RE = /^[0-9a-f]{40}$/i;
|
|
4268
4323
|
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
4269
4324
|
INTEGRITY_RE = /^(?:sha256|sha512)-[A-Za-z0-9+/]+=*$/;
|
|
4325
|
+
SLUG_HEX_TAIL_RE = /^[0-9a-f]{10,16}$/i;
|
|
4270
4326
|
URL_SPAN_RE = /\bhttps?:\/\/[^\s<>"'\\]+/g;
|
|
4271
4327
|
URL_TRAILING_PUNCTUATION_RE = /[.,;:!?)\]}]$/;
|
|
4272
4328
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.20",
|
|
4
4
|
"description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|