Something went wrong. Try again.
My website. cameron.stream
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151import { readFileSync } from "node:fs";import { relative, resolve, sep } from "node:path";
export type KnowledgeKind = | "agent" | "concept" | "journal" | "lesson" | "map" | "organization" | "person" | "place" | "practice" | "project";
interface SourceMapping { pattern: string; decision: "stage" | "manual" | "deny"; kind: KnowledgeKind; topics: string[];}
export interface KnowledgePolicy { version: number; defaultDecision: "deny"; vaultRoot: string; sourceMappings: SourceMapping[]; blockedPrefixes: string[]; blockedWikilinkPrefixes: string[]; allowedRelationshipPredicates: string[]; allowedPeopleSlugs: string[]; peopleDefault: "deny";}
export interface SourceDecision { relativePath: string; decision: SourceMapping["decision"] | "deny"; mapping?: SourceMapping; reason: string;}
export function loadKnowledgePolicy( path = resolve(process.cwd(), "knowledge/policy.json"),): KnowledgePolicy { const policy = JSON.parse(readFileSync(path, "utf8")) as KnowledgePolicy; policy.vaultRoot = policy.vaultRoot.replace( /^\$HOME(?=\/|$)/, process.env.HOME ?? "", ); return policy;}
function normalizePath(path: string): string { return path.split(sep).join("/").replace(/^\.\//, "");}
function matchesPattern(path: string, pattern: string): boolean { const escaped = pattern .replace(/[.+?^${}()|[\]\\]/g, "\\$&") .replace(/\*\*/g, "\0") .replace(/\*/g, "[^/]*") .replace(/\0/g, ".*"); return new RegExp(`^${escaped}$`).test(path);}
export function decideKnowledgeSource( sourcePath: string, policy: KnowledgePolicy,): SourceDecision { const vaultRoot = resolve(policy.vaultRoot); const absolute = resolve(sourcePath); const relativePath = normalizePath(relative(vaultRoot, absolute));
if (relativePath.startsWith("../") || relativePath === "..") { return { relativePath, decision: "deny", reason: "source is outside the configured vault" }; }
const blocked = policy.blockedPrefixes.find((prefix) => relativePath.startsWith(prefix)); if (blocked) { return { relativePath, decision: "deny", reason: `source is under blocked prefix ${blocked}` }; }
const mapping = policy.sourceMappings.find((item) => matchesPattern(relativePath, item.pattern)); if (!mapping) { return { relativePath, decision: policy.defaultDecision, reason: "no allowlisted source mapping" }; }
return { relativePath, decision: mapping.decision, mapping, reason: `matched ${mapping.pattern}`, };}
export interface PrivacyFinding { severity: "block" | "review"; code: string; detail: string;}
export function scanKnowledgeDraft( body: string, policy: KnowledgePolicy,): PrivacyFinding[] { const findings: PrivacyFinding[] = []; const wikilinks = [...body.matchAll(/\[\[([^\]|#]+)(?:[|#][^\]]*)?\]\]/g)];
for (const match of wikilinks) { const target = match[1].trim(); const blocked = policy.blockedWikilinkPrefixes.find((prefix) => target.startsWith(prefix)); findings.push({ severity: blocked ? "block" : "review", code: blocked ? "private-wikilink" : "unmapped-wikilink", detail: target, }); }
const checks: Array<[RegExp, PrivacyFinding["severity"], string, string]> = [ [/\/(?:home|Users)\/[A-Za-z0-9._/-]+/g, "block", "local-path", "local filesystem path"], [/\b[\w.+-]+@[\w.-]+\.[A-Za-z]{2,}\b/g, "review", "email-address", "email address"], [/(?:telegram|signal|discord):\s*\d+/gi, "block", "private-route", "private channel identifier"], [/\b(?:api[_ -]?key|app password|secret|credential)\b/gi, "review", "credential-language", "credential-related language"], [/<(?:script|iframe|object|embed)\b/gi, "block", "active-html", "active HTML"], ];
for (const [pattern, severity, code, label] of checks) { if (pattern.test(body)) findings.push({ severity, code, detail: label }); }
return findings;}
export function publicizeObsidianMarkdown(body: string, title: string): string { let transformed = body .replace(/^\[\[(?:agents\/co-3|co-3)(?:\|[^\]]+)?\]\]\s+said:\s*\n+/im, "") .replace(/\[\[([^\]|#]+)\|([^\]]+)\]\]/g, "$2") .replace(/\[\[([^\]#]+)(?:#[^\]]+)?\]\]/g, (_match, target: string) => { const label = target.split("/").pop() ?? target; return label.replace(/[-_]/g, " "); }) .trim();
const firstHeading = transformed.match(/^#\s+(.+)\n+/); if (firstHeading?.[1].trim().toLowerCase() === title.trim().toLowerCase()) { transformed = transformed.slice(firstHeading[0].length).trim(); }
return transformed;}