@signetai/connector-claude-code 0.193.0 → 0.193.2
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/index.js +389 -13
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -6916,6 +6916,99 @@ var PIPELINE_PROVIDER_CHOICES = [
|
|
|
6916
6916
|
var SYNTHESIS_PROVIDER_CHOICES = PIPELINE_PROVIDER_CHOICES.filter((provider) => provider !== "command");
|
|
6917
6917
|
var PIPELINE_PROVIDER_SET = new Set(PIPELINE_PROVIDER_CHOICES);
|
|
6918
6918
|
var SYNTHESIS_PROVIDER_SET = new Set(SYNTHESIS_PROVIDER_CHOICES);
|
|
6919
|
+
var MEMORY_CONTENT_SAFETY_POLICY_VERSION = "memory-content-safety-v1";
|
|
6920
|
+
var MEMORY_CONTENT_SAFETY_REASONS = [
|
|
6921
|
+
"prompt_injection",
|
|
6922
|
+
"exfiltration",
|
|
6923
|
+
"credential_harvesting",
|
|
6924
|
+
"malicious_shell",
|
|
6925
|
+
"tool_directive",
|
|
6926
|
+
"invisible_unicode"
|
|
6927
|
+
];
|
|
6928
|
+
var INVISIBLE_UNICODE_RE = /(?:\u034f|[\u00ad\u061c\u070f\u180e\u200b\u200c\u200e\u200f\u202a-\u202e\u2060\u2066-\u2069\u206a-\u206f\ufeff]|[\u{e0000}-\u{e007f}])/u;
|
|
6929
|
+
var STRONG_DEFENSIVE_CONTEXT_RE = /\b(?:security\s+(?:guidance|discussion|analysis)|threat\s+model|defensive)\b/i;
|
|
6930
|
+
var REPORTING_CONTEXT_RE = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b/i;
|
|
6931
|
+
var REPORTING_BEFORE_RE = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b[\s\S]{0,80}\b(?:say\w*|read\w*|show\w*|flag\w*|detect\w*|describ\w*|demonstrat\w*|contain\w*|match\w*|pattern)\b/i;
|
|
6932
|
+
var REPORTING_AFTER_RE = /\b(?:detector|scanner|classif\w*|flag\w*|pattern|dangerous|unsafe|malicious|hostile|should|would|must|never|do not|don't|avoid|quoted)\b/i;
|
|
6933
|
+
var NEGATED_DIRECTIVE_RE = /\b(?:never|do not|don't|should not|must not|cannot|can't|avoid|prevent|detect|mitigat\w*)\b[\s\S]{0,80}$/i;
|
|
6934
|
+
var PROMPT_INJECTION_RES = [
|
|
6935
|
+
/\b(?:ignore|disregard|override|forget|bypass)\b[\s\S]{0,100}\b(?:previous|prior|above|earlier|system|developer|assistant|safety|security)?\s*(?:instructions?|rules?|prompt|message)\b/i,
|
|
6936
|
+
/\b(?:new|following|these)\s+(?:(?:system|developer|assistant|hidden)\s+)?instructions?\b/i,
|
|
6937
|
+
/(?:^|\n)\s*(?:system|developer|instruction|prompt)\s*:/im,
|
|
6938
|
+
/<\s*(?:system|developer|assistant|instruction|prompt)\b[^>]*>/i,
|
|
6939
|
+
/\b(?:you are now|act as|roleplay as|pretend to be)\b[\s\S]{0,80}\b(?:system|admin|developer|unrestricted|jailbreak|different agent)\b/i
|
|
6940
|
+
];
|
|
6941
|
+
var TOOL_DIRECTIVE_RES = [
|
|
6942
|
+
/<\s*(?:tool[_-]?call|function[_-]?call|invoke|tool)\b/i,
|
|
6943
|
+
/\b(?:assistant|system)\s+to\s*=\s*[a-z0-9_.-]+/i,
|
|
6944
|
+
/\b(?:call|invoke|use|run|execute)\s+(?:the\s+)?[a-z0-9_.-]+\s+tool\b/i
|
|
6945
|
+
];
|
|
6946
|
+
var EXFILTRATION_RE = /\b(?:reveal|show|print|send|upload|exfiltrat\w*|dump|forward|leak|transmit|export)\b[\s\S]{0,120}(?:\b(?:system\s+prompt|hidden\s+instructions?|secret(?:s)?|credential(?:s)?|password(?:s)?|api\s*keys?|tokens?|private\s+keys?|environment\s+variables?)\b|\.env\b|~\/(?:\.ssh)\/\S+|\/etc\/(?:shadow|passwd)\b)/i;
|
|
6947
|
+
var EXFILTRATION_REVERSE = /(?:\b(?:system\s+prompt|hidden\s+instructions?|secret(?:s)?|credential(?:s)?|password(?:s)?|api\s*keys?|tokens?|private\s+keys?|environment\s+variables?)\b|\.env\b|~\/(?:\.ssh)\/\S+|\/etc\/(?:shadow|passwd)\b)[\s\S]{0,120}\b(?:reveal|show|print|send|upload|exfiltrat\w*|dump|forward|leak|transmit|export)\b/i;
|
|
6948
|
+
var CREDENTIAL_HARVESTING_RE = /\b(?:enter|paste|provide|share|send|give|submit|type|hand over)\b[\s\S]{0,80}\b(?:password|api\s*key|token|secret|credential|private\s+key)\b/i;
|
|
6949
|
+
var DANGEROUS_SHELL_RE = /\b(?:curl|wget)\b[^\n]{0,240}\|\s*(?:ba|z|fi)?sh\b|\brm\s+-rf\s+(?:\/|~|\.ssh)[^\n]{0,240}|\b(?:cat|head|tail)\s+~\/?\.ssh\/(?:id_[a-z]+|authorized_keys)\b|\b(?:printenv|env)\b[^\n]{0,120}\b(?:curl|wget|send|upload|post)\b/i;
|
|
6950
|
+
function matchHasDefensiveContext(content, match) {
|
|
6951
|
+
if (!match || !match[0])
|
|
6952
|
+
return false;
|
|
6953
|
+
const start = match.index ?? 0;
|
|
6954
|
+
const before = content.slice(Math.max(0, start - 120), start);
|
|
6955
|
+
const after = content.slice(start + match[0].length, start + match[0].length + 160);
|
|
6956
|
+
return STRONG_DEFENSIVE_CONTEXT_RE.test(match[0]) || NEGATED_DIRECTIVE_RE.test(before) || STRONG_DEFENSIVE_CONTEXT_RE.test(before) || STRONG_DEFENSIVE_CONTEXT_RE.test(after) || REPORTING_BEFORE_RE.test(before) || REPORTING_CONTEXT_RE.test(before) && REPORTING_AFTER_RE.test(after);
|
|
6957
|
+
}
|
|
6958
|
+
function hasActionableMatch(content, patterns) {
|
|
6959
|
+
return patterns.some((pattern) => {
|
|
6960
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
6961
|
+
const searchable = new RegExp(pattern.source, flags);
|
|
6962
|
+
let match;
|
|
6963
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
6964
|
+
if (!matchHasDefensiveContext(content, match))
|
|
6965
|
+
return true;
|
|
6966
|
+
if (match[0].length === 0)
|
|
6967
|
+
searchable.lastIndex += 1;
|
|
6968
|
+
}
|
|
6969
|
+
return false;
|
|
6970
|
+
});
|
|
6971
|
+
}
|
|
6972
|
+
function hasDangerousShell(content) {
|
|
6973
|
+
const searchable = new RegExp(DANGEROUS_SHELL_RE.source, `${DANGEROUS_SHELL_RE.flags}g`);
|
|
6974
|
+
let match;
|
|
6975
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
6976
|
+
if (matchHasDefensiveContext(content, match))
|
|
6977
|
+
continue;
|
|
6978
|
+
const end = (match.index ?? 0) + match[0].length;
|
|
6979
|
+
const after = content.slice(end, end + 160);
|
|
6980
|
+
if (!STRONG_DEFENSIVE_CONTEXT_RE.test(after) && !REPORTING_AFTER_RE.test(after))
|
|
6981
|
+
return true;
|
|
6982
|
+
if (match[0].length === 0)
|
|
6983
|
+
searchable.lastIndex += 1;
|
|
6984
|
+
}
|
|
6985
|
+
return false;
|
|
6986
|
+
}
|
|
6987
|
+
function scanMemoryContent(content) {
|
|
6988
|
+
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
6989
|
+
const normalized = raw.normalize("NFKC");
|
|
6990
|
+
const reasons = new Set;
|
|
6991
|
+
if (INVISIBLE_UNICODE_RE.test(raw))
|
|
6992
|
+
reasons.add("invisible_unicode");
|
|
6993
|
+
if (hasActionableMatch(normalized, PROMPT_INJECTION_RES))
|
|
6994
|
+
reasons.add("prompt_injection");
|
|
6995
|
+
if (hasActionableMatch(normalized, TOOL_DIRECTIVE_RES))
|
|
6996
|
+
reasons.add("tool_directive");
|
|
6997
|
+
if (hasActionableMatch(normalized, [EXFILTRATION_RE, EXFILTRATION_REVERSE]))
|
|
6998
|
+
reasons.add("exfiltration");
|
|
6999
|
+
if (hasActionableMatch(normalized, [CREDENTIAL_HARVESTING_RE]))
|
|
7000
|
+
reasons.add("credential_harvesting");
|
|
7001
|
+
if (hasDangerousShell(normalized))
|
|
7002
|
+
reasons.add("malicious_shell");
|
|
7003
|
+
const orderedReasons = MEMORY_CONTENT_SAFETY_REASONS.filter((reason) => reasons.has(reason));
|
|
7004
|
+
const status = orderedReasons.length === 0 ? "clean" : orderedReasons.every((reason) => reason === "invisible_unicode") ? "tainted" : "blocked";
|
|
7005
|
+
return {
|
|
7006
|
+
status,
|
|
7007
|
+
contextEligible: status === "clean",
|
|
7008
|
+
reasons: orderedReasons,
|
|
7009
|
+
policyVersion: MEMORY_CONTENT_SAFETY_POLICY_VERSION
|
|
7010
|
+
};
|
|
7011
|
+
}
|
|
6919
7012
|
var DAEMON_DERIVED_MEMORY_SOURCE_TYPES = ["extract", "aggregate-recall", "session_end", "checkpoint", "dreaming"];
|
|
6920
7013
|
var MEMORIES_FTS_TOKENIZER = "unicode61";
|
|
6921
7014
|
function normalizeSql(sql) {
|
|
@@ -10894,6 +10987,95 @@ function up124(db) {
|
|
|
10894
10987
|
ON imported_source_lifecycle(agent_id, status, updated_at DESC);
|
|
10895
10988
|
`);
|
|
10896
10989
|
}
|
|
10990
|
+
function tableExists2(db, table) {
|
|
10991
|
+
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
10992
|
+
}
|
|
10993
|
+
function hasColumn24(db, table, column) {
|
|
10994
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().some((row) => row.name === column);
|
|
10995
|
+
}
|
|
10996
|
+
function backfill(db, rows, sourceKind, scannedAt) {
|
|
10997
|
+
const statement = db.prepare(`INSERT INTO memory_content_safety
|
|
10998
|
+
(agent_id, source_kind, source_id, status, context_eligible, reasons_json, policy_version, scanned_at)
|
|
10999
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
11000
|
+
ON CONFLICT(agent_id, source_kind, source_id) DO UPDATE SET
|
|
11001
|
+
status = excluded.status,
|
|
11002
|
+
context_eligible = excluded.context_eligible,
|
|
11003
|
+
reasons_json = excluded.reasons_json,
|
|
11004
|
+
policy_version = excluded.policy_version,
|
|
11005
|
+
scanned_at = excluded.scanned_at`);
|
|
11006
|
+
for (const row of rows) {
|
|
11007
|
+
const sourceId = row.source_id?.trim();
|
|
11008
|
+
if (!sourceId)
|
|
11009
|
+
continue;
|
|
11010
|
+
const assessment = scanMemoryContent(row.content ?? "");
|
|
11011
|
+
statement.run(row.agent_id?.trim() || "default", sourceKind, sourceId, assessment.status, assessment.contextEligible ? 1 : 0, JSON.stringify(assessment.reasons), MEMORY_CONTENT_SAFETY_POLICY_VERSION, scannedAt);
|
|
11012
|
+
}
|
|
11013
|
+
}
|
|
11014
|
+
function backfillTable(db, params) {
|
|
11015
|
+
if (!tableExists2(db, params.table) || !hasColumn24(db, params.table, params.sourceIdColumn) || !hasColumn24(db, params.table, params.contentColumn))
|
|
11016
|
+
return;
|
|
11017
|
+
const agentColumn = hasColumn24(db, params.table, "agent_id") ? "COALESCE(NULLIF(TRIM(agent_id), ''), 'default')" : "'default'";
|
|
11018
|
+
const rows = db.prepare(`SELECT ${agentColumn} AS agent_id, ${params.sourceIdColumn} AS source_id, ${params.contentColumn} AS content
|
|
11019
|
+
FROM ${params.table}${params.where ? ` WHERE ${params.where}` : ""}`).all();
|
|
11020
|
+
backfill(db, rows, params.sourceKind, params.scannedAt);
|
|
11021
|
+
}
|
|
11022
|
+
function up125(db) {
|
|
11023
|
+
db.exec(`
|
|
11024
|
+
CREATE TABLE IF NOT EXISTS memory_content_safety (
|
|
11025
|
+
agent_id TEXT NOT NULL,
|
|
11026
|
+
source_kind TEXT NOT NULL CHECK (source_kind IN ('memory', 'artifact', 'transcript', 'summary', 'source_chunk')),
|
|
11027
|
+
source_id TEXT NOT NULL,
|
|
11028
|
+
status TEXT NOT NULL CHECK (status IN ('clean', 'tainted', 'blocked')),
|
|
11029
|
+
context_eligible INTEGER NOT NULL CHECK (context_eligible IN (0, 1)),
|
|
11030
|
+
reasons_json TEXT NOT NULL DEFAULT '[]',
|
|
11031
|
+
policy_version TEXT NOT NULL,
|
|
11032
|
+
scanned_at TEXT NOT NULL,
|
|
11033
|
+
PRIMARY KEY (agent_id, source_kind, source_id)
|
|
11034
|
+
);
|
|
11035
|
+
|
|
11036
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_status
|
|
11037
|
+
ON memory_content_safety(agent_id, status, source_kind);
|
|
11038
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_eligibility
|
|
11039
|
+
ON memory_content_safety(agent_id, source_kind, context_eligible);
|
|
11040
|
+
`);
|
|
11041
|
+
const scannedAt = new Date().toISOString();
|
|
11042
|
+
backfillTable(db, {
|
|
11043
|
+
table: "memories",
|
|
11044
|
+
sourceKind: "memory",
|
|
11045
|
+
sourceIdColumn: "id",
|
|
11046
|
+
contentColumn: "content",
|
|
11047
|
+
scannedAt
|
|
11048
|
+
});
|
|
11049
|
+
backfillTable(db, {
|
|
11050
|
+
table: "memory_artifacts",
|
|
11051
|
+
sourceKind: "artifact",
|
|
11052
|
+
sourceIdColumn: "source_path",
|
|
11053
|
+
contentColumn: "content",
|
|
11054
|
+
scannedAt
|
|
11055
|
+
});
|
|
11056
|
+
backfillTable(db, {
|
|
11057
|
+
table: "session_transcripts",
|
|
11058
|
+
sourceKind: "transcript",
|
|
11059
|
+
sourceIdColumn: "session_key",
|
|
11060
|
+
contentColumn: "content",
|
|
11061
|
+
scannedAt
|
|
11062
|
+
});
|
|
11063
|
+
backfillTable(db, {
|
|
11064
|
+
table: "session_summaries",
|
|
11065
|
+
sourceKind: "summary",
|
|
11066
|
+
sourceIdColumn: "id",
|
|
11067
|
+
contentColumn: "content",
|
|
11068
|
+
scannedAt
|
|
11069
|
+
});
|
|
11070
|
+
backfillTable(db, {
|
|
11071
|
+
table: "embeddings",
|
|
11072
|
+
sourceKind: "source_chunk",
|
|
11073
|
+
sourceIdColumn: "id",
|
|
11074
|
+
contentColumn: "chunk_text",
|
|
11075
|
+
where: "source_type IN ('source_chunk', 'source_obsidian_chunk')",
|
|
11076
|
+
scannedAt
|
|
11077
|
+
});
|
|
11078
|
+
}
|
|
10897
11079
|
var MIGRATIONS = [
|
|
10898
11080
|
{
|
|
10899
11081
|
version: 1,
|
|
@@ -11902,6 +12084,12 @@ var MIGRATIONS = [
|
|
|
11902
12084
|
artifacts: {
|
|
11903
12085
|
tables: ["imported_source_lifecycle"]
|
|
11904
12086
|
}
|
|
12087
|
+
},
|
|
12088
|
+
{
|
|
12089
|
+
version: 125,
|
|
12090
|
+
name: "memory-content-safety",
|
|
12091
|
+
up: up125,
|
|
12092
|
+
artifacts: { tables: ["memory_content_safety"] }
|
|
11905
12093
|
}
|
|
11906
12094
|
];
|
|
11907
12095
|
var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
|
|
@@ -19144,6 +19332,99 @@ var PIPELINE_PROVIDER_CHOICES2 = [
|
|
|
19144
19332
|
var SYNTHESIS_PROVIDER_CHOICES2 = PIPELINE_PROVIDER_CHOICES2.filter((provider) => provider !== "command");
|
|
19145
19333
|
var PIPELINE_PROVIDER_SET2 = new Set(PIPELINE_PROVIDER_CHOICES2);
|
|
19146
19334
|
var SYNTHESIS_PROVIDER_SET2 = new Set(SYNTHESIS_PROVIDER_CHOICES2);
|
|
19335
|
+
var MEMORY_CONTENT_SAFETY_POLICY_VERSION2 = "memory-content-safety-v1";
|
|
19336
|
+
var MEMORY_CONTENT_SAFETY_REASONS2 = [
|
|
19337
|
+
"prompt_injection",
|
|
19338
|
+
"exfiltration",
|
|
19339
|
+
"credential_harvesting",
|
|
19340
|
+
"malicious_shell",
|
|
19341
|
+
"tool_directive",
|
|
19342
|
+
"invisible_unicode"
|
|
19343
|
+
];
|
|
19344
|
+
var INVISIBLE_UNICODE_RE2 = /(?:\u034f|[\u00ad\u061c\u070f\u180e\u200b\u200c\u200e\u200f\u202a-\u202e\u2060\u2066-\u2069\u206a-\u206f\ufeff]|[\u{e0000}-\u{e007f}])/u;
|
|
19345
|
+
var STRONG_DEFENSIVE_CONTEXT_RE2 = /\b(?:security\s+(?:guidance|discussion|analysis)|threat\s+model|defensive)\b/i;
|
|
19346
|
+
var REPORTING_CONTEXT_RE2 = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b/i;
|
|
19347
|
+
var REPORTING_BEFORE_RE2 = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b[\s\S]{0,80}\b(?:say\w*|read\w*|show\w*|flag\w*|detect\w*|describ\w*|demonstrat\w*|contain\w*|match\w*|pattern)\b/i;
|
|
19348
|
+
var REPORTING_AFTER_RE2 = /\b(?:detector|scanner|classif\w*|flag\w*|pattern|dangerous|unsafe|malicious|hostile|should|would|must|never|do not|don't|avoid|quoted)\b/i;
|
|
19349
|
+
var NEGATED_DIRECTIVE_RE2 = /\b(?:never|do not|don't|should not|must not|cannot|can't|avoid|prevent|detect|mitigat\w*)\b[\s\S]{0,80}$/i;
|
|
19350
|
+
var PROMPT_INJECTION_RES2 = [
|
|
19351
|
+
/\b(?:ignore|disregard|override|forget|bypass)\b[\s\S]{0,100}\b(?:previous|prior|above|earlier|system|developer|assistant|safety|security)?\s*(?:instructions?|rules?|prompt|message)\b/i,
|
|
19352
|
+
/\b(?:new|following|these)\s+(?:(?:system|developer|assistant|hidden)\s+)?instructions?\b/i,
|
|
19353
|
+
/(?:^|\n)\s*(?:system|developer|instruction|prompt)\s*:/im,
|
|
19354
|
+
/<\s*(?:system|developer|assistant|instruction|prompt)\b[^>]*>/i,
|
|
19355
|
+
/\b(?:you are now|act as|roleplay as|pretend to be)\b[\s\S]{0,80}\b(?:system|admin|developer|unrestricted|jailbreak|different agent)\b/i
|
|
19356
|
+
];
|
|
19357
|
+
var TOOL_DIRECTIVE_RES2 = [
|
|
19358
|
+
/<\s*(?:tool[_-]?call|function[_-]?call|invoke|tool)\b/i,
|
|
19359
|
+
/\b(?:assistant|system)\s+to\s*=\s*[a-z0-9_.-]+/i,
|
|
19360
|
+
/\b(?:call|invoke|use|run|execute)\s+(?:the\s+)?[a-z0-9_.-]+\s+tool\b/i
|
|
19361
|
+
];
|
|
19362
|
+
var EXFILTRATION_RE2 = /\b(?:reveal|show|print|send|upload|exfiltrat\w*|dump|forward|leak|transmit|export)\b[\s\S]{0,120}(?:\b(?:system\s+prompt|hidden\s+instructions?|secret(?:s)?|credential(?:s)?|password(?:s)?|api\s*keys?|tokens?|private\s+keys?|environment\s+variables?)\b|\.env\b|~\/(?:\.ssh)\/\S+|\/etc\/(?:shadow|passwd)\b)/i;
|
|
19363
|
+
var EXFILTRATION_REVERSE2 = /(?:\b(?:system\s+prompt|hidden\s+instructions?|secret(?:s)?|credential(?:s)?|password(?:s)?|api\s*keys?|tokens?|private\s+keys?|environment\s+variables?)\b|\.env\b|~\/(?:\.ssh)\/\S+|\/etc\/(?:shadow|passwd)\b)[\s\S]{0,120}\b(?:reveal|show|print|send|upload|exfiltrat\w*|dump|forward|leak|transmit|export)\b/i;
|
|
19364
|
+
var CREDENTIAL_HARVESTING_RE2 = /\b(?:enter|paste|provide|share|send|give|submit|type|hand over)\b[\s\S]{0,80}\b(?:password|api\s*key|token|secret|credential|private\s+key)\b/i;
|
|
19365
|
+
var DANGEROUS_SHELL_RE2 = /\b(?:curl|wget)\b[^\n]{0,240}\|\s*(?:ba|z|fi)?sh\b|\brm\s+-rf\s+(?:\/|~|\.ssh)[^\n]{0,240}|\b(?:cat|head|tail)\s+~\/?\.ssh\/(?:id_[a-z]+|authorized_keys)\b|\b(?:printenv|env)\b[^\n]{0,120}\b(?:curl|wget|send|upload|post)\b/i;
|
|
19366
|
+
function matchHasDefensiveContext2(content, match) {
|
|
19367
|
+
if (!match || !match[0])
|
|
19368
|
+
return false;
|
|
19369
|
+
const start = match.index ?? 0;
|
|
19370
|
+
const before = content.slice(Math.max(0, start - 120), start);
|
|
19371
|
+
const after = content.slice(start + match[0].length, start + match[0].length + 160);
|
|
19372
|
+
return STRONG_DEFENSIVE_CONTEXT_RE2.test(match[0]) || NEGATED_DIRECTIVE_RE2.test(before) || STRONG_DEFENSIVE_CONTEXT_RE2.test(before) || STRONG_DEFENSIVE_CONTEXT_RE2.test(after) || REPORTING_BEFORE_RE2.test(before) || REPORTING_CONTEXT_RE2.test(before) && REPORTING_AFTER_RE2.test(after);
|
|
19373
|
+
}
|
|
19374
|
+
function hasActionableMatch2(content, patterns) {
|
|
19375
|
+
return patterns.some((pattern) => {
|
|
19376
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
19377
|
+
const searchable = new RegExp(pattern.source, flags);
|
|
19378
|
+
let match;
|
|
19379
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
19380
|
+
if (!matchHasDefensiveContext2(content, match))
|
|
19381
|
+
return true;
|
|
19382
|
+
if (match[0].length === 0)
|
|
19383
|
+
searchable.lastIndex += 1;
|
|
19384
|
+
}
|
|
19385
|
+
return false;
|
|
19386
|
+
});
|
|
19387
|
+
}
|
|
19388
|
+
function hasDangerousShell2(content) {
|
|
19389
|
+
const searchable = new RegExp(DANGEROUS_SHELL_RE2.source, `${DANGEROUS_SHELL_RE2.flags}g`);
|
|
19390
|
+
let match;
|
|
19391
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
19392
|
+
if (matchHasDefensiveContext2(content, match))
|
|
19393
|
+
continue;
|
|
19394
|
+
const end = (match.index ?? 0) + match[0].length;
|
|
19395
|
+
const after = content.slice(end, end + 160);
|
|
19396
|
+
if (!STRONG_DEFENSIVE_CONTEXT_RE2.test(after) && !REPORTING_AFTER_RE2.test(after))
|
|
19397
|
+
return true;
|
|
19398
|
+
if (match[0].length === 0)
|
|
19399
|
+
searchable.lastIndex += 1;
|
|
19400
|
+
}
|
|
19401
|
+
return false;
|
|
19402
|
+
}
|
|
19403
|
+
function scanMemoryContent2(content) {
|
|
19404
|
+
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
19405
|
+
const normalized = raw.normalize("NFKC");
|
|
19406
|
+
const reasons = new Set;
|
|
19407
|
+
if (INVISIBLE_UNICODE_RE2.test(raw))
|
|
19408
|
+
reasons.add("invisible_unicode");
|
|
19409
|
+
if (hasActionableMatch2(normalized, PROMPT_INJECTION_RES2))
|
|
19410
|
+
reasons.add("prompt_injection");
|
|
19411
|
+
if (hasActionableMatch2(normalized, TOOL_DIRECTIVE_RES2))
|
|
19412
|
+
reasons.add("tool_directive");
|
|
19413
|
+
if (hasActionableMatch2(normalized, [EXFILTRATION_RE2, EXFILTRATION_REVERSE2]))
|
|
19414
|
+
reasons.add("exfiltration");
|
|
19415
|
+
if (hasActionableMatch2(normalized, [CREDENTIAL_HARVESTING_RE2]))
|
|
19416
|
+
reasons.add("credential_harvesting");
|
|
19417
|
+
if (hasDangerousShell2(normalized))
|
|
19418
|
+
reasons.add("malicious_shell");
|
|
19419
|
+
const orderedReasons = MEMORY_CONTENT_SAFETY_REASONS2.filter((reason) => reasons.has(reason));
|
|
19420
|
+
const status = orderedReasons.length === 0 ? "clean" : orderedReasons.every((reason) => reason === "invisible_unicode") ? "tainted" : "blocked";
|
|
19421
|
+
return {
|
|
19422
|
+
status,
|
|
19423
|
+
contextEligible: status === "clean",
|
|
19424
|
+
reasons: orderedReasons,
|
|
19425
|
+
policyVersion: MEMORY_CONTENT_SAFETY_POLICY_VERSION2
|
|
19426
|
+
};
|
|
19427
|
+
}
|
|
19147
19428
|
var DAEMON_DERIVED_MEMORY_SOURCE_TYPES2 = ["extract", "aggregate-recall", "session_end", "checkpoint", "dreaming"];
|
|
19148
19429
|
var MEMORIES_FTS_TOKENIZER2 = "unicode61";
|
|
19149
19430
|
function normalizeSql2(sql) {
|
|
@@ -19195,7 +19476,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
|
|
|
19195
19476
|
return true;
|
|
19196
19477
|
return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
|
|
19197
19478
|
}
|
|
19198
|
-
function
|
|
19479
|
+
function up126(db) {
|
|
19199
19480
|
db.exec(`
|
|
19200
19481
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
19201
19482
|
version INTEGER PRIMARY KEY,
|
|
@@ -19284,12 +19565,12 @@ function up125(db) {
|
|
|
19284
19565
|
} catch {}
|
|
19285
19566
|
createMemoriesFts2(db);
|
|
19286
19567
|
}
|
|
19287
|
-
function
|
|
19568
|
+
function hasColumn25(db, table, column) {
|
|
19288
19569
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
19289
19570
|
return rows.some((r) => r.name === column);
|
|
19290
19571
|
}
|
|
19291
19572
|
function addColumnIfMissing27(db, table, column, definition) {
|
|
19292
|
-
if (!
|
|
19573
|
+
if (!hasColumn25(db, table, column)) {
|
|
19293
19574
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
19294
19575
|
}
|
|
19295
19576
|
}
|
|
@@ -19439,12 +19720,12 @@ function up310(db) {
|
|
|
19439
19720
|
WHERE content_hash IS NOT NULL AND is_deleted = 0
|
|
19440
19721
|
`);
|
|
19441
19722
|
}
|
|
19442
|
-
function
|
|
19723
|
+
function hasColumn26(db, table, column) {
|
|
19443
19724
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
19444
19725
|
return rows.some((r) => r.name === column);
|
|
19445
19726
|
}
|
|
19446
19727
|
function addColumnIfMissing32(db, table, column, definition) {
|
|
19447
|
-
if (!
|
|
19728
|
+
if (!hasColumn26(db, table, column)) {
|
|
19448
19729
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
19449
19730
|
}
|
|
19450
19731
|
}
|
|
@@ -19638,7 +19919,7 @@ function up1110(db) {
|
|
|
19638
19919
|
ON session_scores(session_key);
|
|
19639
19920
|
`);
|
|
19640
19921
|
}
|
|
19641
|
-
function
|
|
19922
|
+
function up127(db) {
|
|
19642
19923
|
db.exec(`
|
|
19643
19924
|
CREATE TABLE IF NOT EXISTS scheduled_tasks (
|
|
19644
19925
|
id TEXT PRIMARY KEY,
|
|
@@ -22430,7 +22711,7 @@ function up1032(db) {
|
|
|
22430
22711
|
)
|
|
22431
22712
|
`);
|
|
22432
22713
|
}
|
|
22433
|
-
function
|
|
22714
|
+
function tableExists3(db, table) {
|
|
22434
22715
|
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) !== undefined;
|
|
22435
22716
|
}
|
|
22436
22717
|
function hasColumn162(db, table, column) {
|
|
@@ -22452,7 +22733,7 @@ function up1042(db) {
|
|
|
22452
22733
|
CREATE INDEX IF NOT EXISTS idx_derived_memory_sources_source
|
|
22453
22734
|
ON derived_memory_sources(agent_id, source_kind, source_id);
|
|
22454
22735
|
`);
|
|
22455
|
-
if (
|
|
22736
|
+
if (tableExists3(db, "aggregate_evidence_sources")) {
|
|
22456
22737
|
db.exec(`
|
|
22457
22738
|
INSERT OR IGNORE INTO derived_memory_sources
|
|
22458
22739
|
(derived_memory_id, source_kind, source_id, source_path, agent_id, created_at)
|
|
@@ -22460,7 +22741,7 @@ function up1042(db) {
|
|
|
22460
22741
|
FROM aggregate_evidence_sources
|
|
22461
22742
|
`);
|
|
22462
22743
|
}
|
|
22463
|
-
if (
|
|
22744
|
+
if (tableExists3(db, "aggregate_memory_sources")) {
|
|
22464
22745
|
db.exec(`
|
|
22465
22746
|
INSERT OR IGNORE INTO derived_memory_sources
|
|
22466
22747
|
(derived_memory_id, source_kind, source_id, source_path, agent_id, created_at)
|
|
@@ -22468,10 +22749,10 @@ function up1042(db) {
|
|
|
22468
22749
|
FROM aggregate_memory_sources
|
|
22469
22750
|
`);
|
|
22470
22751
|
}
|
|
22471
|
-
if (
|
|
22752
|
+
if (tableExists3(db, "memories") && !hasColumn162(db, "memories", "stale_at")) {
|
|
22472
22753
|
db.exec("ALTER TABLE memories ADD COLUMN stale_at TEXT");
|
|
22473
22754
|
}
|
|
22474
|
-
if (
|
|
22755
|
+
if (tableExists3(db, "memories")) {
|
|
22475
22756
|
db.exec(`
|
|
22476
22757
|
CREATE INDEX IF NOT EXISTS idx_memories_stale_derived
|
|
22477
22758
|
ON memories(agent_id, stale_at)
|
|
@@ -23122,11 +23403,100 @@ function up1242(db) {
|
|
|
23122
23403
|
ON imported_source_lifecycle(agent_id, status, updated_at DESC);
|
|
23123
23404
|
`);
|
|
23124
23405
|
}
|
|
23406
|
+
function tableExists22(db, table) {
|
|
23407
|
+
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
23408
|
+
}
|
|
23409
|
+
function hasColumn242(db, table, column) {
|
|
23410
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().some((row) => row.name === column);
|
|
23411
|
+
}
|
|
23412
|
+
function backfill2(db, rows, sourceKind, scannedAt) {
|
|
23413
|
+
const statement = db.prepare(`INSERT INTO memory_content_safety
|
|
23414
|
+
(agent_id, source_kind, source_id, status, context_eligible, reasons_json, policy_version, scanned_at)
|
|
23415
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
23416
|
+
ON CONFLICT(agent_id, source_kind, source_id) DO UPDATE SET
|
|
23417
|
+
status = excluded.status,
|
|
23418
|
+
context_eligible = excluded.context_eligible,
|
|
23419
|
+
reasons_json = excluded.reasons_json,
|
|
23420
|
+
policy_version = excluded.policy_version,
|
|
23421
|
+
scanned_at = excluded.scanned_at`);
|
|
23422
|
+
for (const row of rows) {
|
|
23423
|
+
const sourceId = row.source_id?.trim();
|
|
23424
|
+
if (!sourceId)
|
|
23425
|
+
continue;
|
|
23426
|
+
const assessment = scanMemoryContent2(row.content ?? "");
|
|
23427
|
+
statement.run(row.agent_id?.trim() || "default", sourceKind, sourceId, assessment.status, assessment.contextEligible ? 1 : 0, JSON.stringify(assessment.reasons), MEMORY_CONTENT_SAFETY_POLICY_VERSION2, scannedAt);
|
|
23428
|
+
}
|
|
23429
|
+
}
|
|
23430
|
+
function backfillTable2(db, params) {
|
|
23431
|
+
if (!tableExists22(db, params.table) || !hasColumn242(db, params.table, params.sourceIdColumn) || !hasColumn242(db, params.table, params.contentColumn))
|
|
23432
|
+
return;
|
|
23433
|
+
const agentColumn = hasColumn242(db, params.table, "agent_id") ? "COALESCE(NULLIF(TRIM(agent_id), ''), 'default')" : "'default'";
|
|
23434
|
+
const rows = db.prepare(`SELECT ${agentColumn} AS agent_id, ${params.sourceIdColumn} AS source_id, ${params.contentColumn} AS content
|
|
23435
|
+
FROM ${params.table}${params.where ? ` WHERE ${params.where}` : ""}`).all();
|
|
23436
|
+
backfill2(db, rows, params.sourceKind, params.scannedAt);
|
|
23437
|
+
}
|
|
23438
|
+
function up1252(db) {
|
|
23439
|
+
db.exec(`
|
|
23440
|
+
CREATE TABLE IF NOT EXISTS memory_content_safety (
|
|
23441
|
+
agent_id TEXT NOT NULL,
|
|
23442
|
+
source_kind TEXT NOT NULL CHECK (source_kind IN ('memory', 'artifact', 'transcript', 'summary', 'source_chunk')),
|
|
23443
|
+
source_id TEXT NOT NULL,
|
|
23444
|
+
status TEXT NOT NULL CHECK (status IN ('clean', 'tainted', 'blocked')),
|
|
23445
|
+
context_eligible INTEGER NOT NULL CHECK (context_eligible IN (0, 1)),
|
|
23446
|
+
reasons_json TEXT NOT NULL DEFAULT '[]',
|
|
23447
|
+
policy_version TEXT NOT NULL,
|
|
23448
|
+
scanned_at TEXT NOT NULL,
|
|
23449
|
+
PRIMARY KEY (agent_id, source_kind, source_id)
|
|
23450
|
+
);
|
|
23451
|
+
|
|
23452
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_status
|
|
23453
|
+
ON memory_content_safety(agent_id, status, source_kind);
|
|
23454
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_eligibility
|
|
23455
|
+
ON memory_content_safety(agent_id, source_kind, context_eligible);
|
|
23456
|
+
`);
|
|
23457
|
+
const scannedAt = new Date().toISOString();
|
|
23458
|
+
backfillTable2(db, {
|
|
23459
|
+
table: "memories",
|
|
23460
|
+
sourceKind: "memory",
|
|
23461
|
+
sourceIdColumn: "id",
|
|
23462
|
+
contentColumn: "content",
|
|
23463
|
+
scannedAt
|
|
23464
|
+
});
|
|
23465
|
+
backfillTable2(db, {
|
|
23466
|
+
table: "memory_artifacts",
|
|
23467
|
+
sourceKind: "artifact",
|
|
23468
|
+
sourceIdColumn: "source_path",
|
|
23469
|
+
contentColumn: "content",
|
|
23470
|
+
scannedAt
|
|
23471
|
+
});
|
|
23472
|
+
backfillTable2(db, {
|
|
23473
|
+
table: "session_transcripts",
|
|
23474
|
+
sourceKind: "transcript",
|
|
23475
|
+
sourceIdColumn: "session_key",
|
|
23476
|
+
contentColumn: "content",
|
|
23477
|
+
scannedAt
|
|
23478
|
+
});
|
|
23479
|
+
backfillTable2(db, {
|
|
23480
|
+
table: "session_summaries",
|
|
23481
|
+
sourceKind: "summary",
|
|
23482
|
+
sourceIdColumn: "id",
|
|
23483
|
+
contentColumn: "content",
|
|
23484
|
+
scannedAt
|
|
23485
|
+
});
|
|
23486
|
+
backfillTable2(db, {
|
|
23487
|
+
table: "embeddings",
|
|
23488
|
+
sourceKind: "source_chunk",
|
|
23489
|
+
sourceIdColumn: "id",
|
|
23490
|
+
contentColumn: "chunk_text",
|
|
23491
|
+
where: "source_type IN ('source_chunk', 'source_obsidian_chunk')",
|
|
23492
|
+
scannedAt
|
|
23493
|
+
});
|
|
23494
|
+
}
|
|
23125
23495
|
var MIGRATIONS2 = [
|
|
23126
23496
|
{
|
|
23127
23497
|
version: 1,
|
|
23128
23498
|
name: "baseline",
|
|
23129
|
-
up:
|
|
23499
|
+
up: up126,
|
|
23130
23500
|
artifacts: { tables: ["memories", "conversations", "embeddings"] }
|
|
23131
23501
|
},
|
|
23132
23502
|
{
|
|
@@ -23198,7 +23568,7 @@ var MIGRATIONS2 = [
|
|
|
23198
23568
|
{
|
|
23199
23569
|
version: 12,
|
|
23200
23570
|
name: "scheduled-tasks",
|
|
23201
|
-
up:
|
|
23571
|
+
up: up127,
|
|
23202
23572
|
artifacts: { tables: ["scheduled_tasks", "task_runs"] }
|
|
23203
23573
|
},
|
|
23204
23574
|
{
|
|
@@ -24130,6 +24500,12 @@ var MIGRATIONS2 = [
|
|
|
24130
24500
|
artifacts: {
|
|
24131
24501
|
tables: ["imported_source_lifecycle"]
|
|
24132
24502
|
}
|
|
24503
|
+
},
|
|
24504
|
+
{
|
|
24505
|
+
version: 125,
|
|
24506
|
+
name: "memory-content-safety",
|
|
24507
|
+
up: up1252,
|
|
24508
|
+
artifacts: { tables: ["memory_content_safety"] }
|
|
24133
24509
|
}
|
|
24134
24510
|
];
|
|
24135
24511
|
var LATEST_SCHEMA_VERSION2 = MIGRATIONS2[MIGRATIONS2.length - 1]?.version ?? 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signetai/connector-claude-code",
|
|
3
|
-
"version": "0.193.
|
|
3
|
+
"version": "0.193.2",
|
|
4
4
|
"description": "Signet connector for Claude Code (Anthropic CLI)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"typecheck": "tsc --noEmit"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@signetai/connector-base": "0.193.
|
|
28
|
-
"@signetai/core": "0.193.
|
|
27
|
+
"@signetai/connector-base": "0.193.2",
|
|
28
|
+
"@signetai/core": "0.193.2"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^22.0.0",
|