@cmnwlth/core 0.1.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 @@
1
+ {"version":3,"sources":["../src/schema.ts","../src/config.ts","../src/ids.ts","../src/notes.ts","../src/scaffold.ts","../src/secrets-gitleaks.generated.ts","../src/secrets.ts","../src/index-db.ts","../src/registry.ts","../src/source.ts","../src/health.ts","../src/lock.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * The four note kinds that make up a brain. See docs/02-data-model.md.\n * One concept per file; kind determines the folder it lives in.\n */\nexport const NOTE_KINDS = [\"memory\", \"decision\", \"work-state\", \"person\"] as const;\nexport type NoteKind = (typeof NOTE_KINDS)[number];\n\n/** Folder each kind is stored in, relative to the brain root. */\nexport const KIND_DIR: Record<NoteKind, string> = {\n memory: \"memory\",\n decision: \"decisions\",\n \"work-state\": \"work-state\",\n person: \"people\",\n};\n\n/**\n * Dates are stored as `YYYY-MM-DD` strings. YAML parsers coerce unquoted dates to\n * JS `Date`; this preprocessor normalizes both back to the canonical string form.\n */\nexport const IsoDate = z.preprocess(\n (v) => (v instanceof Date ? v.toISOString().slice(0, 10) : v),\n z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/, \"expected a YYYY-MM-DD date\"),\n);\n\n/**\n * A note `id` must be a single, safe filename segment: it is the file's stem and is joined onto\n * the brain path to build the canonical write path (`<kind>/<id>.md`). Rejecting slashes and\n * `..` here — at the one point every note (written or read) is validated — stops a crafted id\n * (`../../evil`) from escaping the brain on approve/write (#77). Legitimate ids from `makeNoteId`\n * are `<date>-<slug>-<suffix>`, which never contain these.\n */\nconst SafeId = z\n .string()\n .min(1)\n .refine((s) => !s.includes(\"/\") && !s.includes(\"\\\\\") && s !== \".\" && s !== \"..\", {\n message: \"id must be a single path segment (no '/', '\\\\\\\\', or '..')\",\n });\n\n/** Fields common to every note kind. */\nconst baseShape = {\n id: SafeId,\n title: z.string().min(1),\n tags: z.array(z.string()).default([]),\n created: IsoDate,\n updated: IsoDate.optional(),\n author: z.string().optional(),\n /**\n * Originating project the note was captured from — a stable repo identity (git `origin`\n * slug, else the repo-root basename). Lets a shared brain group/filter notes by project\n * (ADR-0015). Optional: pre-existing and non-project notes are \"unattributed\".\n */\n source: z.string().optional(),\n /** Wikilink targets (`[[id]]` or bare id) to related notes. */\n relates: z.array(z.string()).default([]),\n};\n\nexport const MemoryFrontmatter = z\n .object({\n ...baseShape,\n kind: z.literal(\"memory\"),\n status: z.enum([\"active\", \"superseded\", \"stale\"]).default(\"active\"),\n /** Last time this fact was checked against reality (Kage-style verification). */\n verified: IsoDate.optional(),\n sources: z.array(z.string()).default([]),\n superseded_by: z.string().nullable().optional(),\n })\n .passthrough();\nexport type MemoryFrontmatter = z.infer<typeof MemoryFrontmatter>;\n\nexport const DecisionFrontmatter = z\n .object({\n ...baseShape,\n kind: z.literal(\"decision\"),\n status: z.enum([\"proposed\", \"accepted\", \"superseded\"]).default(\"proposed\"),\n supersedes: z.array(z.string()).default([]),\n superseded_by: z.string().nullable().optional(),\n deciders: z.array(z.string()).default([]),\n })\n .passthrough();\nexport type DecisionFrontmatter = z.infer<typeof DecisionFrontmatter>;\n\nexport const WorkStateFrontmatter = z\n .object({\n ...baseShape,\n kind: z.literal(\"work-state\"),\n owner: z.string().optional(),\n status: z.enum([\"planned\", \"in-progress\", \"blocked\", \"done\"]).default(\"planned\"),\n })\n .passthrough();\nexport type WorkStateFrontmatter = z.infer<typeof WorkStateFrontmatter>;\n\nexport const PersonFrontmatter = z\n .object({\n ...baseShape,\n kind: z.literal(\"person\"),\n name: z.string().min(1),\n org: z.string().optional(),\n role: z.string().optional(),\n })\n .passthrough();\nexport type PersonFrontmatter = z.infer<typeof PersonFrontmatter>;\n\n/**\n * Discriminated union over `kind` — the validated frontmatter of any note. Each member is\n * `.passthrough()` so unknown keys survive parse→serialize (#81): a field this build's schema\n * doesn't know (a user's custom key, or one a newer schema added) is preserved rather than\n * silently dropped when a note is re-serialized (e.g. sync's conflict sibling rewrite).\n */\nexport const Frontmatter = z.discriminatedUnion(\"kind\", [\n MemoryFrontmatter,\n DecisionFrontmatter,\n WorkStateFrontmatter,\n PersonFrontmatter,\n]);\nexport type Frontmatter = z.infer<typeof Frontmatter>;\n\n/** A parsed note: validated frontmatter + markdown body + repo-relative path. */\nexport interface Note {\n frontmatter: Frontmatter;\n /** Markdown content after the frontmatter block. */\n body: string;\n /** Path relative to the brain root, e.g. `memory/2026-07-01-foo-a1b2.md`. */\n path: string;\n}\n\n/** Current on-disk schema version, pinned in `.commonwealth/schema-version`. */\nexport const SCHEMA_VERSION = 1;\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { SCHEMA_VERSION } from \"./schema.js\";\nimport type { ScanOptions } from \"./secrets.js\";\n\n/**\n * Brain-level (shared, synced) configuration, stored at `<brain>/.commonwealth/config.json`\n * (ADR-0009). Distinct from the per-user, unsynced scope config at `~/.commonwealth/config.json`\n * (ADR-0008). Because it lives in the repo, `features` apply to the whole team.\n */\nexport interface BrainConfig {\n /** Human-readable brain name (defaults to the brain directory's basename). */\n name: string;\n /** On-disk schema version this brain is pinned to. */\n schemaVersion: number;\n /** Configured git remotes for sync (names or URLs). */\n remotes: string[];\n /** Free-form curation settings, reserved for the curator seam (ADR-0007). */\n curation: Record<string, unknown>;\n /** Team-wide feature toggles; see {@link FEATURE_FLAGS}. */\n features: Record<string, boolean>;\n /**\n * Secret-scanner tuning (#46), committed so it applies team-wide. `entropy` opts into\n * high-entropy detection beyond the named patterns; `allowlist` holds accepted values /\n * known false positives to suppress. Off + empty by default (preserves the zero-FP default).\n */\n secretScan: { entropy: boolean; allowlist: string[] };\n}\n\n/** Build the {@link ScanOptions} for the secret scanner from a brain's config (#46). */\nexport function scanOptions(config: BrainConfig): ScanOptions {\n return { detectEntropy: config.secretScan.entropy, allowlist: config.secretScan.allowlist };\n}\n\n/**\n * Registry of the known feature flags: their name, a human-readable description, and the\n * default (off unless a team opts in). New flags are added here; scaffold and\n * {@link defaultBrainConfig} build the `features` block from this list.\n */\nexport const FEATURE_FLAGS: ReadonlyArray<{\n name: string;\n description: string;\n default: boolean;\n}> = [\n {\n name: \"autoAdr\",\n description: \"Auto-create ADR/decision notes in the brain when a decision is captured\",\n default: false,\n },\n {\n name: \"autoPromote\",\n description:\n \"Auto-promote captured notes straight into canon instead of holding them in the review \" +\n \"queue. Curation gating (dedup/validation) still applies; only the manual review step is \" +\n \"skipped (ADR-0014). Set false to require manual /commonwealth:promote.\",\n default: true,\n },\n];\n\n/** Build the default `features` map from {@link FEATURE_FLAGS} (each flag at its default). */\nfunction defaultFeatures(): Record<string, boolean> {\n const features: Record<string, boolean> = {};\n for (const flag of FEATURE_FLAGS) {\n features[flag.name] = flag.default;\n }\n return features;\n}\n\n/**\n * A fresh {@link BrainConfig} for a brain named `name`: no remotes, empty curation, and the\n * `features` block filled from {@link FEATURE_FLAGS} defaults. Pinned to `SCHEMA_VERSION`.\n */\nexport function defaultBrainConfig(name: string): BrainConfig {\n return {\n name,\n schemaVersion: SCHEMA_VERSION,\n remotes: [],\n curation: {},\n features: defaultFeatures(),\n secretScan: { entropy: false, allowlist: [] },\n };\n}\n\n/** Brains already warned about a schema skew this process, so the warning fires once each. */\nconst schemaSkewWarned = new Set<string>();\n\n/** Warn (once per brain per process) that the on-disk config is a newer schema than this code. */\nfunction warnSchemaSkewOnce(brainDir: string, found: number): void {\n const key = path.resolve(brainDir);\n if (schemaSkewWarned.has(key)) return;\n schemaSkewWarned.add(key);\n console.error(\n `[commonwealth] brain at ${key} is schema v${found} but this build understands v${SCHEMA_VERSION}; ` +\n `some fields may not be read correctly — upgrade Commonwealth.`,\n );\n}\n\n/** Path of the brain config relative to the brain root. */\nconst CONFIG_REL = path.join(\".commonwealth\", \"config.json\");\n\n/** Absolute path to a brain's shared config file (`<brainDir>/.commonwealth/config.json`). */\nexport function brainConfigPath(brainDir: string): string {\n return path.join(brainDir, CONFIG_REL);\n}\n\n/**\n * Load a brain's shared config, merged over {@link defaultBrainConfig} so any missing\n * top-level field AND any missing feature key is filled in (file values win; unknown\n * feature keys present in the file are preserved). Never throws on a missing or unparseable\n * file — returns the defaults in that case.\n */\nexport async function loadBrainConfig(brainDir: string): Promise<BrainConfig> {\n const defaults = defaultBrainConfig(path.basename(path.resolve(brainDir)));\n\n let raw: string;\n try {\n raw = await fs.readFile(brainConfigPath(brainDir), \"utf8\");\n } catch {\n return defaults;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return defaults;\n }\n\n const obj = (typeof parsed === \"object\" && parsed !== null ? parsed : {}) as Partial<BrainConfig>;\n\n // Detect a brain written by a NEWER schema than this code understands (#101): silently\n // proceeding could mis-read forward-version fields. Warn once per brain rather than throw —\n // the config still loads best-effort — so a version skew is at least visible.\n if (typeof obj.schemaVersion === \"number\" && obj.schemaVersion > SCHEMA_VERSION) {\n warnSchemaSkewOnce(brainDir, obj.schemaVersion);\n }\n\n return {\n name: typeof obj.name === \"string\" ? obj.name : defaults.name,\n schemaVersion:\n typeof obj.schemaVersion === \"number\" ? obj.schemaVersion : defaults.schemaVersion,\n remotes: Array.isArray(obj.remotes) ? obj.remotes : defaults.remotes,\n curation:\n typeof obj.curation === \"object\" && obj.curation !== null ? obj.curation : defaults.curation,\n // Defaults first so missing flags are filled; file values win, unknown keys preserved.\n features: {\n ...defaults.features,\n ...(typeof obj.features === \"object\" && obj.features !== null ? obj.features : {}),\n },\n secretScan: normalizeSecretScan(obj.secretScan, defaults.secretScan),\n };\n}\n\n/** Coerce a config file's `secretScan` into the typed shape, falling back to defaults per field. */\nfunction normalizeSecretScan(\n raw: unknown,\n fallback: BrainConfig[\"secretScan\"],\n): BrainConfig[\"secretScan\"] {\n if (typeof raw !== \"object\" || raw === null) return fallback;\n const obj = raw as Partial<BrainConfig[\"secretScan\"]>;\n return {\n entropy: typeof obj.entropy === \"boolean\" ? obj.entropy : fallback.entropy,\n allowlist:\n Array.isArray(obj.allowlist) && obj.allowlist.every((v) => typeof v === \"string\")\n ? obj.allowlist\n : fallback.allowlist,\n };\n}\n\n/**\n * Persist a brain's shared config as pretty (2-space) JSON with a trailing newline at\n * {@link brainConfigPath}, creating the `.commonwealth/` parent directory if needed.\n */\nexport async function saveBrainConfig(brainDir: string, config: BrainConfig): Promise<void> {\n const file = brainConfigPath(brainDir);\n await fs.mkdir(path.dirname(file), { recursive: true });\n // Atomic write (tmp + rename): a crash mid-write must not leave a torn config.json, which\n // `loadBrainConfig` would fail to parse and silently replace with defaults — flipping\n // team settings like `autoPromote` back on (#101). Rename is atomic on the same filesystem.\n const tmp = `${file}.${process.pid}.tmp`;\n await fs.writeFile(tmp, `${JSON.stringify(config, null, 2)}\\n`, \"utf8\");\n await fs.rename(tmp, file);\n}\n\n/**\n * True when `feature` is enabled in the brain's shared config. Unknown or unset flags are\n * treated as disabled (`false`). Never throws on a missing config file.\n */\nexport async function isFeatureEnabled(brainDir: string, feature: string): Promise<boolean> {\n const config = await loadBrainConfig(brainDir);\n return Boolean(config.features[feature]);\n}\n\n/**\n * Set `feature` to `on` in the brain's shared config and persist it (load-modify-save).\n * Missing top-level fields and feature keys are filled from defaults on the way through.\n */\nexport async function setFeature(brainDir: string, feature: string, on: boolean): Promise<void> {\n const config = await loadBrainConfig(brainDir);\n config.features[feature] = on;\n await saveBrainConfig(brainDir, config);\n}\n","import GithubSlugger from \"github-slugger\";\nimport { customAlphabet } from \"nanoid\";\nimport { KIND_DIR, type NoteKind } from \"./schema.js\";\n\n/**\n * 4-char lowercase-alphanumeric suffix. ~1.7M values — its only job is to make two\n * concurrent writes of the same title+date produce *different* filenames, so git\n * unions them instead of conflicting. See ADR-0003.\n */\nconst nano = customAlphabet(\"0123456789abcdefghijklmnopqrstuvwxyz\", 4);\n\n/** A fresh collision-avoidance suffix. */\nexport function shortId(): string {\n return nano();\n}\n\n/** URL/filename-safe slug of a title, capped so filenames stay reasonable. */\nexport function slugify(title: string): string {\n const slugger = new GithubSlugger();\n const slug = slugger.slug(title).slice(0, 60);\n return slug.replace(/-+$/, \"\");\n}\n\n/**\n * Build a note id of the form `<created>-<slug>-<shortid>`, e.g.\n * `2026-07-01-auth-choice-a1b2`. The id equals the filename stem and is stable.\n */\nexport function makeNoteId(title: string, created: string, suffix: string = shortId()): string {\n return `${created}-${slugify(title)}-${suffix}`;\n}\n\n/**\n * A filesystem-safe single path segment for a project `source` (ADR-0015). The source may be\n * an `owner/repo` slug; we flatten separators so a project is exactly one folder level\n * (`<project>/<kind>/<id>.md`), keeping the tree a fixed depth. The full source stays in\n * frontmatter. Empty/invalid input yields \"\" (→ unattributed, note lives at the kind root).\n */\nexport function sourceSegment(source: string | undefined): string {\n if (typeof source !== \"string\") return \"\";\n const seg = source\n .trim()\n .replace(/[^a-zA-Z0-9._-]+/g, \"-\")\n .replace(/^[-.]+|[-.]+$/g, \"\")\n .slice(0, 80);\n return seg;\n}\n\n/**\n * Repo-relative path for a note. With a project `source` the note lives under a per-project\n * subtree (`<project>/<kind>/<id>.md`, ADR-0015); without one it stays at the kind root\n * (`<kind>/<id>.md`) — which is also the back-compat location for pre-provenance notes.\n */\nexport function pathForNote(kind: NoteKind, id: string, source?: string): string {\n const seg = sourceSegment(source);\n return seg ? `${seg}/${KIND_DIR[kind]}/${id}.md` : `${KIND_DIR[kind]}/${id}.md`;\n}\n\n/** `YYYY-MM-DD` for a given date (defaults to now). */\nexport function today(date: Date = new Date()): string {\n return date.toISOString().slice(0, 10);\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport matter from \"gray-matter\";\nimport { makeNoteId, pathForNote, shortId, today } from \"./ids.js\";\nimport { Frontmatter, KIND_DIR, type Note, type NoteKind } from \"./schema.js\";\n\n/**\n * Input to create a new note. `id`, `created` (defaults to today), and the file path are\n * derived; kind-specific fields (e.g. a decision's `deciders`) go in `fields` and are\n * validated against the schema.\n */\nexport interface NewNoteInput {\n kind: NoteKind;\n title: string;\n body: string;\n tags?: string[];\n author?: string;\n /** Originating project (git repo identity); recorded as frontmatter `source` (ADR-0015). */\n source?: string;\n /** `YYYY-MM-DD`; defaults to today. */\n created?: string;\n /** Extra kind-specific frontmatter fields, validated against the schema. */\n fields?: Record<string, unknown>;\n}\n\n/** Preferred frontmatter key order for stable, readable, diff-friendly output. */\nconst KEY_ORDER = [\n \"id\",\n \"kind\",\n \"title\",\n \"name\",\n \"org\",\n \"role\",\n \"owner\",\n \"status\",\n \"tags\",\n \"created\",\n \"updated\",\n \"author\",\n \"source\",\n \"verified\",\n \"deciders\",\n \"supersedes\",\n \"superseded_by\",\n \"sources\",\n \"relates\",\n];\n\nfunction orderFrontmatter(fm: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const key of KEY_ORDER) {\n if (key in fm && fm[key] !== undefined) out[key] = fm[key];\n }\n // Preserve any unknown keys the schema let through, appended in stable order.\n for (const key of Object.keys(fm).sort()) {\n if (!(key in out) && fm[key] !== undefined) out[key] = fm[key];\n }\n return out;\n}\n\n/**\n * Parse a raw markdown-with-frontmatter string into a validated {@link Note}.\n * Throws (zod) if the frontmatter does not satisfy the schema for its `kind`.\n */\nexport function parseNote(raw: string, notePath: string): Note {\n const parsed = matter(raw);\n const frontmatter = Frontmatter.parse(parsed.data);\n return { frontmatter, body: parsed.content.trim(), path: notePath };\n}\n\n/**\n * Resolve `relPath` under `brainDir` and assert it stays inside the brain (path containment).\n * A `relPath` containing `../` — from a malicious MCP `read` arg or an attacker-controlled note\n * id — would otherwise escape the brain and read/write arbitrary files (#76, #77). Boundary-safe:\n * `/brain` does not contain `/brainiac`. Returns the resolved absolute path.\n */\nexport function resolveWithinBrain(brainDir: string, relPath: string): string {\n const base = path.resolve(brainDir);\n const abs = path.resolve(base, relPath);\n if (abs !== base && !abs.startsWith(base + path.sep)) {\n throw new Error(`Path escapes the brain directory: ${relPath}`);\n }\n return abs;\n}\n\n/** Serialize a {@link Note} back to canonical `---`-fenced frontmatter + body. */\nexport function serializeNote(note: Note): string {\n const ordered = orderFrontmatter(note.frontmatter as unknown as Record<string, unknown>);\n const body = note.body.trim();\n return matter.stringify(body ? `${body}\\n` : \"\", ordered);\n}\n\n/**\n * Create a new note atomically under `brainDir`. The id embeds a random suffix\n * (`makeNoteId`), so two concurrent writers of the same title+date produce distinct\n * files that git unions rather than conflicts (ADR-0003). Writes to a temp file then\n * renames, so readers never observe a partial file.\n */\nexport async function writeNote(brainDir: string, input: NewNoteInput): Promise<Note> {\n const created = input.created ?? today();\n const id = makeNoteId(input.title, created);\n const relPath = pathForNote(input.kind, id, input.source);\n const absPath = resolveWithinBrain(brainDir, relPath);\n\n // Spread caller `fields` FIRST so the derived, trusted keys below always win. Otherwise a\n // candidate carrying `fields: { id: \"../../evil\" }` would override the safe derived id and\n // desync frontmatter.id from the filename — the injection point behind #77.\n const raw: Record<string, unknown> = {\n ...(input.fields ?? {}),\n id,\n kind: input.kind,\n title: input.title,\n tags: input.tags ?? [],\n created,\n ...(input.author ? { author: input.author } : {}),\n ...(input.source ? { source: input.source } : {}),\n };\n const frontmatter = Frontmatter.parse(raw);\n const note: Note = { frontmatter, body: input.body.trim(), path: relPath };\n const content = serializeNote(note);\n\n await fs.mkdir(path.dirname(absPath), { recursive: true });\n const tmp = `${absPath}.${shortId()}.tmp`;\n await fs.writeFile(tmp, content, \"utf8\");\n // Publish via link+unlink rather than rename so an id collision fails CLOSED: `fs.link`\n // throws EEXIST if the note path already exists, whereas `fs.rename` would silently\n // overwrite the existing note (#101). makeNoteId's random suffix makes a real collision\n // astronomically rare, but \"never silently overwrite\" is a core invariant (ADR-0003).\n try {\n await fs.link(tmp, absPath);\n } catch (err) {\n await fs.rm(tmp, { force: true });\n if ((err as NodeJS.ErrnoException).code === \"EEXIST\") {\n throw new Error(`Refusing to overwrite an existing note at ${relPath} (id collision)`);\n }\n throw err;\n }\n await fs.rm(tmp, { force: true });\n return note;\n}\n\n/**\n * Overwrite an existing note's file with `note` (its `path`), atomically (tmp + rename). Unlike\n * {@link writeNote} this INTENDS to replace an existing file — used to supersede a note in place\n * (#29), never to create. Throws if the resolved path escapes the brain (#76).\n */\nexport async function overwriteNote(brainDir: string, note: Note): Promise<void> {\n const absPath = resolveWithinBrain(brainDir, note.path);\n const content = serializeNote(note);\n await fs.mkdir(path.dirname(absPath), { recursive: true });\n const tmp = `${absPath}.${shortId()}.tmp`;\n await fs.writeFile(tmp, content, \"utf8\");\n await fs.rename(tmp, absPath); // replace in place — supersede-not-delete keeps the file\n}\n\n/**\n * Mark a memory/decision note superseded IN PLACE (supersede-not-delete, ADR-0008/#29): set\n * `status: \"superseded\"` and `superseded_by: <survivorId>`, additive so it union-merges. Only\n * memory and decision carry these fields; other kinds are returned unchanged (no-op). Returns\n * the updated note, or the original when it isn't a supersede-able kind / is already superseded\n * by the same survivor.\n */\nexport async function supersedeNote(\n brainDir: string,\n relPath: string,\n survivorId: string,\n): Promise<Note> {\n const note = await readNote(brainDir, relPath);\n const fm = note.frontmatter;\n if (fm.kind !== \"memory\" && fm.kind !== \"decision\") return note;\n if (fm.status === \"superseded\" && fm.superseded_by === survivorId) return note;\n const updated: Note = {\n ...note,\n frontmatter: { ...fm, status: \"superseded\", superseded_by: survivorId },\n };\n await overwriteNote(brainDir, updated);\n return updated;\n}\n\n/** Read and parse a single note by its repo-relative path. */\nexport async function readNote(brainDir: string, relPath: string): Promise<Note> {\n const raw = await fs.readFile(resolveWithinBrain(brainDir, relPath), \"utf8\");\n return parseNote(raw, relPath);\n}\n\n/** Folder names that hold notes (the values of {@link KIND_DIR}); a note's parent dir. */\nconst KIND_FOLDERS = new Set<string>(Object.values(KIND_DIR));\n\n/** Top-level dirs that never contain notes and must not be walked (derived/local/vcs). */\nconst NON_NOTE_DIRS = new Set([\".git\", \".commonwealth\", \"index\", \"staging\", \"node_modules\"]);\n\n/**\n * List all notes, optionally filtered to one kind. Layout-agnostic (ADR-0015): notes may live\n * at the kind root (`<kind>/<id>.md`, unattributed) or under a per-project subtree\n * (`<project>/<kind>/<id>.md`). A file is a note when its PARENT folder is a kind folder and it\n * is not the generated `INDEX.md`; the authoritative kind comes from frontmatter. Skips derived\n * (`index/`), local (`staging/`), and vcs dirs so canon never includes staged/derived files.\n */\nexport async function listNotes(brainDir: string, kind?: NoteKind): Promise<Note[]> {\n const found: string[] = [];\n\n async function walk(absDir: string): Promise<void> {\n let entries: import(\"node:fs\").Dirent[];\n try {\n entries = await fs.readdir(absDir, { withFileTypes: true });\n } catch {\n return; // dir may not exist yet\n }\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (NON_NOTE_DIRS.has(entry.name)) continue;\n await walk(path.join(absDir, entry.name));\n } else if (\n entry.isFile() &&\n entry.name.endsWith(\".md\") &&\n entry.name !== \"INDEX.md\" &&\n KIND_FOLDERS.has(path.basename(absDir))\n ) {\n found.push(path.relative(brainDir, path.join(absDir, entry.name)));\n }\n }\n }\n\n await walk(brainDir);\n\n const notes: Note[] = [];\n for (const rel of found.sort()) {\n // Resilience (#80): one malformed/corrupt note (bad frontmatter, hand-edit, partial write)\n // must NOT take down the whole read path — listNotes feeds search, the index, and the derived\n // router, so a single throw here was a brain-wide read outage. Skip the bad note with a\n // stderr breadcrumb and keep going; the rest of canon stays readable.\n let note: Note;\n try {\n note = await readNote(brainDir, rel);\n } catch (err) {\n console.error(\n `[commonwealth] skipping unreadable note ${rel}: ${err instanceof Error ? err.message : err}`,\n );\n continue;\n }\n if (!kind || note.frontmatter.kind === kind) notes.push(note);\n }\n return notes;\n}\n","import { execFile } from \"node:child_process\";\nimport { existsSync, promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { defaultBrainConfig } from \"./config.js\";\nimport { KIND_DIR, type NoteKind, SCHEMA_VERSION } from \"./schema.js\";\n\nconst pexec = promisify(execFile);\n\nexport interface InitBrainOptions {\n /** Human-readable brain name, written into COMMONWEALTH.md / .commonwealth/config. */\n name?: string;\n /** Proceed even if the directory already contains files. */\n force?: boolean;\n}\n\n/** The four kind folders, in stable order, each tracked empty via a `.gitkeep`. */\nconst KIND_DIRS: readonly string[] = Object.values(KIND_DIR);\n\n/** Human-readable heading label for each kind folder's `INDEX.md`. */\nconst KIND_INDEX_TITLE: Record<string, string> = {\n memory: \"Memory\",\n decisions: \"Decisions\",\n \"work-state\": \"Work-state\",\n people: \"People\",\n};\n\n/** Entries that don't count as \"pre-existing content\" when deciding to abort. */\nconst IGNORED_ENTRIES = new Set([\".git\", \".gitkeep\"]);\n\n/** Top-level files/folders a Commonwealth brain owns; their presence means \"already a brain\". */\nconst BRAIN_ENTRIES = new Set<string>([\n \".commonwealth\",\n \".gitattributes\",\n \".gitignore\",\n \"COMMONWEALTH.md\",\n \"index\",\n ...KIND_DIRS,\n]);\n\nconst GITATTRIBUTES = [\"COMMONWEALTH.md merge=union\", \"**/INDEX.md merge=union\", \"\"].join(\"\\n\");\n\n// `staging/` is the per-user review queue — local only, never synced (ADR-0008).\n// `.DS_Store` — macOS drops one into every browsed folder; it must never enter the brain.\nconst GITIGNORE = [\"index/\", \"staging/\", \"*.db\", \"*.db-shm\", \"*.db-wal\", \".DS_Store\", \"\"].join(\n \"\\n\",\n);\n\n/**\n * Make `dir` a git repository with an initial scaffold commit, so the brain is operational\n * the moment `initBrain` returns. A Commonwealth brain *is* a git repo (ADR-0003) — the sync\n * engine's `git add -A` / `commit` / `push` and `git remote add origin` all assume one exists;\n * without it, every git command run inside the brain walks up to the nearest ancestor `.git`\n * and operates on the wrong repository (issue #66, ADR-0013).\n *\n * - No-op when `.git` already exists, so a caller that set up its own repo (e.g. a `git clone`\n * of an existing brain, as the sync fixtures do) is respected and idempotency is preserved.\n * - Falls back to a generic committer identity only when the user has none configured, so the\n * initial commit succeeds on a fresh machine / CI runner without overriding a real identity.\n * - Best-effort: git being absent or failing must not prevent scaffolding a valid brain — we\n * degrade to the previous \"files only\" behavior (never worse than before) rather than throw.\n */\nasync function initGitRepo(dir: string): Promise<void> {\n if (existsSync(path.join(dir, \".git\"))) return;\n try {\n await pexec(\"git\", [\"init\", \"-q\", \"-b\", \"main\", dir]);\n await pexec(\"git\", [\"add\", \"-A\"], { cwd: dir });\n let identity: string[] = [];\n try {\n const email = (await pexec(\"git\", [\"config\", \"user.email\"], { cwd: dir })).stdout.trim();\n if (email.length === 0) throw new Error(\"no identity\");\n } catch {\n identity = [\"-c\", \"user.name=Commonwealth\", \"-c\", \"user.email=commonwealth@localhost\"];\n }\n await pexec(\n \"git\",\n [...identity, \"commit\", \"-q\", \"-m\", \"Initialize Commonwealth brain scaffold\"],\n {\n cwd: dir,\n },\n );\n } catch {\n // git missing / too old / commit failed — leave the scaffolded files as-is.\n }\n}\n\n/**\n * True if `dir` is empty or contains only entries a Commonwealth brain owns (or `.git`).\n * Anything else (a stray README, source tree, etc.) means initializing here would be a\n * surprise, so `initBrain` refuses unless `force` is set.\n */\nasync function isSafeToInit(dir: string): Promise<boolean> {\n // A directory that is ALREADY a brain (has the identity file) is always safe to re-init:\n // initBrain is idempotent and no longer overwrites config (ADR-0013/#75), so re-scaffolding\n // for a reseed is a no-op on existing state. This lets `commonwealth init --reseed` run on a\n // populated brain whose root also holds runtime entries (`staging/`, `.DS_Store`, and the\n // per-project note folders from ADR-0015) that predate/aren't in BRAIN_ENTRIES (#61-followup).\n if (existsSync(path.join(dir, \".commonwealth\", \"schema-version\"))) return true;\n\n let entries: string[];\n try {\n entries = await fs.readdir(dir);\n } catch {\n return true; // dir doesn't exist yet — we'll create it\n }\n for (const entry of entries) {\n if (IGNORED_ENTRIES.has(entry)) continue;\n if (!BRAIN_ENTRIES.has(entry)) return false;\n }\n return true;\n}\n\n/** Write `contents` to `file` (creating parent dirs). Overwrites — the skeleton is generated. */\nasync function writeFile(file: string, contents: string): Promise<void> {\n await fs.mkdir(path.dirname(file), { recursive: true });\n await fs.writeFile(file, contents, \"utf8\");\n}\n\n/**\n * Write `contents` to `file` only if it does not already exist (creating parent dirs). Used for\n * files that hold real, team-modifiable state (`config.json`, the schema-version pin, the git\n * driver files) so a re-init / `--reseed` on an existing brain never clobbers settings the team\n * changed — e.g. `remotes`, `curation`, or a `false` `autoPromote` (#75). Uses the `wx` open flag\n * (fail-if-exists) so the check-and-write is a single atomic syscall, not a TOCTOU race.\n */\nasync function writeFileIfAbsent(file: string, contents: string): Promise<void> {\n await fs.mkdir(path.dirname(file), { recursive: true });\n try {\n await fs.writeFile(file, contents, { encoding: \"utf8\", flag: \"wx\" });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"EEXIST\") return;\n throw err;\n }\n}\n\n/**\n * Initialize a brain repository skeleton at `dir` (see docs/01-architecture.md §1,\n * docs/02-data-model.md). Creates:\n * - the four kind folders: memory/ decisions/ work-state/ people/ (each with `.gitkeep`)\n * - `.commonwealth/` with `schema-version` and a `config.json` (name, schemaVersion, remotes, curation)\n * - `.gitattributes` with `merge=union` for derived/append-only files (ADR-0003)\n * - `.gitignore` ignoring the derived `index/` and `*.db`\n * - a generated `COMMONWEALTH.md` router and per-folder `INDEX.md` placeholders\n * - a git repository with an initial commit (a brain *is* a git repo; ADR-0003, ADR-0013)\n *\n * Idempotent: safe to call again; missing files are (re)created and an existing `.git` is left\n * untouched. Throws if `dir` already contains non-Commonwealth files and `force` is not set.\n */\nexport async function initBrain(dir: string, opts: InitBrainOptions = {}): Promise<void> {\n if (!opts.force && !(await isSafeToInit(dir))) {\n throw new Error(\n `Refusing to initialize a Commonwealth brain in a non-empty directory: ${dir}. ` +\n `Pass { force: true } to proceed.`,\n );\n }\n\n const name = opts.name ?? path.basename(path.resolve(dir));\n\n await fs.mkdir(dir, { recursive: true });\n\n // Kind folders, each tracked-empty via .gitkeep, plus a per-folder INDEX.md placeholder.\n for (const kindDir of KIND_DIRS) {\n const abs = path.join(dir, kindDir);\n await fs.mkdir(abs, { recursive: true });\n await writeFile(path.join(abs, \".gitkeep\"), \"\");\n const title = KIND_INDEX_TITLE[kindDir] ?? kindDir;\n await writeFile(path.join(abs, \"INDEX.md\"), `# ${title} index\\n\\n_generated_\\n`);\n }\n\n // .commonwealth metadata: schema-version pin + config.json. Written only when absent so a\n // re-init never resets a brain the team already configured (#75): config.json is real,\n // team-owned data (remotes/curation/autoPromote), recoverable only via git archaeology.\n await writeFileIfAbsent(path.join(dir, \".commonwealth\", \"schema-version\"), `${SCHEMA_VERSION}\\n`);\n const config = defaultBrainConfig(name);\n await writeFileIfAbsent(\n path.join(dir, \".commonwealth\", \"config.json\"),\n `${JSON.stringify(config, null, 2)}\\n`,\n );\n\n // Git merge/ignore drivers for derived + disposable artifacts (ADR-0003, ADR-0005). Also\n // absent-only: they're static, but re-writing them serves no purpose and keeps init a no-op.\n await writeFileIfAbsent(path.join(dir, \".gitattributes\"), GITATTRIBUTES);\n await writeFileIfAbsent(path.join(dir, \".gitignore\"), GITIGNORE);\n\n // Minimal generated router placeholder; real content comes from regenerateDerived.\n const commonwealth = [\n `# ${name} — Commonwealth brain`,\n \"\",\n \"_This file is generated. Do not edit by hand — it is regenerated from the note set._\",\n \"\",\n \"Run the Commonwealth index to populate the router with active work-state and recent decisions.\",\n \"\",\n ].join(\"\\n\");\n await writeFile(path.join(dir, \"COMMONWEALTH.md\"), commonwealth);\n\n // A brain is a git repo: init + initial commit so the sync engine has one to operate on\n // (issue #66). No-op if `.git` already exists; best-effort if git is unavailable.\n await initGitRepo(dir);\n}\n\n// Re-export for consumers that want the canonical folder list without touching schema.\nexport const BRAIN_KIND_DIRS: readonly string[] = KIND_DIRS;\nexport type { NoteKind };\n","/**\n * GENERATED — do not edit. Source: gitleaks (MIT). Regenerate: node\n * packages/core/scripts/gen-gitleaks-patterns.mjs\n *\n * Filtered, JS-compatible, false-positive-safe subset of the gitleaks ruleset. Each\n * `re` is global-flagged (and case-insensitive when the source had a leading `(?i)`).\n * Kept 183 of 221 rules; the rest were skipped as generic,\n * too broad, JS-incompatible, or benign-corpus false positives.\n */\n\n/** A gitleaks-derived credential pattern. `kind` is `\"gitleaks:\" + rule.id`. */\nexport const GITLEAKS_PATTERNS: ReadonlyArray<{ kind: string; re: RegExp }> = [\n {\n kind: \"gitleaks:1password-secret-key\",\n re: new RegExp(\n \"\\\\bA3-[A-Z0-9]{6}-(?:(?:[A-Z0-9]{11})|(?:[A-Z0-9]{6}-[A-Z0-9]{5}))-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}\\\\b\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:1password-service-account-token\",\n re: new RegExp(\"ops_eyJ[a-zA-Z0-9+/]{250,}={0,3}\", \"g\"),\n },\n {\n kind: \"gitleaks:adafruit-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:adafruit)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9_-]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:adobe-client-id\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:adobe)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:age-secret-key\",\n re: new RegExp(\"AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}\", \"g\"),\n },\n {\n kind: \"gitleaks:airtable-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:airtable)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{17})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:airtable-personnal-access-token\",\n re: new RegExp(\"\\\\b(pat[A-Za-z0-9]{14}\\\\.[a-f0-9]{64})\\\\b\", \"g\"),\n },\n {\n kind: \"gitleaks:algolia-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:algolia)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:alibaba-secret-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:alibaba)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{30})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:anthropic-admin-api-key\",\n re: new RegExp(\"\\\\b(sk-ant-admin01-[a-zA-Z0-9_\\\\-]{93}AA)(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:anthropic-api-key\",\n re: new RegExp(\"\\\\b(sk-ant-api03-[a-zA-Z0-9_\\\\-]{93}AA)(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n { kind: \"gitleaks:artifactory-api-key\", re: new RegExp(\"\\\\bAKCp[A-Za-z0-9]{69}\\\\b\", \"g\") },\n {\n kind: \"gitleaks:artifactory-reference-token\",\n re: new RegExp(\"\\\\bcmVmd[A-Za-z0-9]{59}\\\\b\", \"g\"),\n },\n {\n kind: \"gitleaks:asana-client-id\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:asana)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([0-9]{16})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:asana-client-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:asana)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:aws-access-token\",\n re: new RegExp(\"\\\\b((?:A3T[A-Z0-9]|AKIA|ASIA|ABIA|ACCA)[A-Z2-7]{16})\\\\b\", \"g\"),\n },\n {\n kind: \"gitleaks:aws-amazon-bedrock-api-key-long-lived\",\n re: new RegExp(\"\\\\b(ABSK[A-Za-z0-9+/]{109,269}={0,2})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:aws-amazon-bedrock-api-key-short-lived\",\n re: new RegExp(\"bedrock-api-key-YmVkcm9jay5hbWF6b25hd3MuY29t\", \"g\"),\n },\n {\n kind: \"gitleaks:azure-ad-client-secret\",\n re: new RegExp(\n \"(?:^|[\\\\\\\\'\\\"\\\\x60\\\\s>=:(,)])([a-zA-Z0-9_~.]{3}\\\\dQ~[a-zA-Z0-9_~.-]{31,34})(?:$|[\\\\\\\\'\\\"\\\\x60\\\\s<),])\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:beamer-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:beamer)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(b_[a-z0-9=_\\\\-]{44})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:bitbucket-client-id\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:bitbucket)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:bitbucket-client-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:bitbucket)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9=_\\\\-]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:bittrex-access-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:bittrex)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:bittrex-secret-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:bittrex)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:clickhouse-cloud-api-secret-key\",\n re: new RegExp(\"\\\\b(4b1d[A-Za-z0-9]{38})\\\\b\", \"g\"),\n },\n { kind: \"gitleaks:clojars-api-token\", re: new RegExp(\"CLOJARS_[a-z0-9]{60}\", \"gi\") },\n {\n kind: \"gitleaks:cloudflare-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:cloudflare)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9_-]{40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:cloudflare-global-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:cloudflare)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{37})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:cloudflare-origin-ca-key\",\n re: new RegExp(\"\\\\b(v1\\\\.0-[a-f0-9]{24}-[a-f0-9]{146})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:codecov-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:codecov)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:coinbase-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:coinbase)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9_-]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:confluent-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:confluent)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{16})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:confluent-secret-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:confluent)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:contentful-delivery-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:contentful)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9=_\\\\-]{43})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:curl-auth-user\",\n re: new RegExp(\n '\\\\bcurl\\\\b(?:.*|.*(?:[\\\\r\\\\n]{1,2}.*){1,5})[ \\\\t\\\\n\\\\r](?:-u|--user)(?:=|[ \\\\t]{0,5})(\"(:[^\"]{3,}|[^:\"]{3,}:|[^:\"]{3,}:[^\"]{3,})\"|\\'([^:\\']{3,}:[^\\']{3,})\\'|((?:\"[^\"]{3,}\"|\\'[^\\']{3,}\\'|[\\\\w$@.-]+):(?:\"[^\"]{3,}\"|\\'[^\\']{3,}\\'|[\\\\w${}@.-]+)))(?:\\\\s|\\\\z)',\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:databricks-api-token\",\n re: new RegExp(\"\\\\b(dapi[a-f0-9]{32}(?:-\\\\d)?)(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:datadog-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:datadog)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:defined-networking-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:dnkey)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(dnkey-[a-z0-9=_\\\\-]{26}-[a-z0-9=_\\\\-]{52})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:digitalocean-access-token\",\n re: new RegExp(\"\\\\b(doo_v1_[a-f0-9]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:digitalocean-pat\",\n re: new RegExp(\"\\\\b(dop_v1_[a-f0-9]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:digitalocean-refresh-token\",\n re: new RegExp(\"\\\\b(dor_v1_[a-f0-9]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"gi\"),\n },\n {\n kind: \"gitleaks:discord-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:discord)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:discord-client-id\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:discord)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([0-9]{18})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:discord-client-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:discord)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9=_\\\\-]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:droneci-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:droneci)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:dropbox-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:dropbox)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{15})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:dropbox-long-lived-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:dropbox)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\\\\-_=]{43})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:dropbox-short-lived-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:dropbox)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(sl\\\\.[a-z0-9\\\\-=_]{135})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:facebook-access-token\",\n re: new RegExp(\"\\\\b(\\\\d{15,16}(\\\\||%)[0-9a-z\\\\-_]{27,40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"gi\"),\n },\n {\n kind: \"gitleaks:facebook-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:facebook)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:fastly-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:fastly)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9=_\\\\-]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:finicity-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:finicity)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:finicity-client-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:finicity)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{20})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:finnhub-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:finnhub)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{20})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:flickr-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:flickr)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:flyio-access-token\",\n re: new RegExp(\n \"\\\\b((?:fo1_[\\\\w-]{43}|fm1[ar]_[a-zA-Z0-9+\\\\/]{100,}={0,3}|fm2_[a-zA-Z0-9+\\\\/]{100,}={0,3}))(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:freemius-secret-key\",\n re: new RegExp(\"[\\\"']secret_key[\\\"']\\\\s*=>\\\\s*[\\\"'](sk_[\\\\S]{29})[\\\"']\", \"gi\"),\n },\n {\n kind: \"gitleaks:freshbooks-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:freshbooks)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:gcp-api-key\",\n re: new RegExp(\"\\\\b(AIza[\\\\w-]{35})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n { kind: \"gitleaks:github-app-token\", re: new RegExp(\"(?:ghu|ghs)_[0-9a-zA-Z]{36}\", \"g\") },\n { kind: \"gitleaks:github-fine-grained-pat\", re: new RegExp(\"github_pat_\\\\w{82}\", \"g\") },\n { kind: \"gitleaks:github-oauth\", re: new RegExp(\"gho_[0-9a-zA-Z]{36}\", \"g\") },\n { kind: \"gitleaks:github-pat\", re: new RegExp(\"ghp_[0-9a-zA-Z]{36}\", \"g\") },\n { kind: \"gitleaks:github-refresh-token\", re: new RegExp(\"ghr_[0-9a-zA-Z]{36}\", \"g\") },\n {\n kind: \"gitleaks:gitlab-cicd-job-token\",\n re: new RegExp(\"glcbt-[0-9a-zA-Z]{1,5}_[0-9a-zA-Z_-]{20}\", \"g\"),\n },\n { kind: \"gitleaks:gitlab-deploy-token\", re: new RegExp(\"gldt-[0-9a-zA-Z_\\\\-]{20}\", \"g\") },\n {\n kind: \"gitleaks:gitlab-feature-flag-client-token\",\n re: new RegExp(\"glffct-[0-9a-zA-Z_\\\\-]{20}\", \"g\"),\n },\n { kind: \"gitleaks:gitlab-feed-token\", re: new RegExp(\"glft-[0-9a-zA-Z_\\\\-]{20}\", \"g\") },\n { kind: \"gitleaks:gitlab-incoming-mail-token\", re: new RegExp(\"glimt-[0-9a-zA-Z_\\\\-]{25}\", \"g\") },\n {\n kind: \"gitleaks:gitlab-kubernetes-agent-token\",\n re: new RegExp(\"glagent-[0-9a-zA-Z_\\\\-]{50}\", \"g\"),\n },\n { kind: \"gitleaks:gitlab-oauth-app-secret\", re: new RegExp(\"gloas-[0-9a-zA-Z_\\\\-]{64}\", \"g\") },\n { kind: \"gitleaks:gitlab-pat\", re: new RegExp(\"glpat-[\\\\w-]{20}\", \"g\") },\n {\n kind: \"gitleaks:gitlab-pat-routable\",\n re: new RegExp(\"\\\\bglpat-[0-9a-zA-Z_-]{27,300}\\\\.[0-9a-z]{2}[0-9a-z]{7}\\\\b\", \"g\"),\n },\n { kind: \"gitleaks:gitlab-ptt\", re: new RegExp(\"glptt-[0-9a-f]{40}\", \"g\") },\n { kind: \"gitleaks:gitlab-rrt\", re: new RegExp(\"GR1348941[\\\\w-]{20}\", \"g\") },\n {\n kind: \"gitleaks:gitlab-runner-authentication-token\",\n re: new RegExp(\"glrt-[0-9a-zA-Z_\\\\-]{20}\", \"g\"),\n },\n {\n kind: \"gitleaks:gitlab-runner-authentication-token-routable\",\n re: new RegExp(\"\\\\bglrt-t\\\\d_[0-9a-zA-Z_\\\\-]{27,300}\\\\.[0-9a-z]{2}[0-9a-z]{7}\\\\b\", \"g\"),\n },\n { kind: \"gitleaks:gitlab-scim-token\", re: new RegExp(\"glsoat-[0-9a-zA-Z_\\\\-]{20}\", \"g\") },\n { kind: \"gitleaks:gitlab-session-cookie\", re: new RegExp(\"_gitlab_session=[0-9a-z]{32}\", \"g\") },\n {\n kind: \"gitleaks:gitter-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:gitter)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9_-]{40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:grafana-api-key\",\n re: new RegExp(\"\\\\b(eyJrIjoi[A-Za-z0-9]{70,400}={0,3})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"gi\"),\n },\n {\n kind: \"gitleaks:grafana-cloud-api-token\",\n re: new RegExp(\"\\\\b(glc_[A-Za-z0-9+/]{32,400}={0,3})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"gi\"),\n },\n {\n kind: \"gitleaks:grafana-service-account-token\",\n re: new RegExp(\"\\\\b(glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"gi\"),\n },\n {\n kind: \"gitleaks:harness-api-key\",\n re: new RegExp(\"(?:pat|sat)\\\\.[a-zA-Z0-9_-]{22}\\\\.[a-zA-Z0-9]{24}\\\\.[a-zA-Z0-9]{20}\", \"g\"),\n },\n {\n kind: \"gitleaks:hashicorp-tf-password\",\n re: new RegExp(\n '[\\\\w.-]{0,50}?(?:administrator_login_password|password)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s\\'\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60\\'\"\\\\s=]{0,5}(\"[a-z0-9=_\\\\-]{8,20}\")(?:[\\\\x60\\'\"\\\\s;]|\\\\\\\\[nr]|$)',\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:heroku-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:heroku)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:heroku-api-key-v2\",\n re: new RegExp(\"\\\\b((HRKU-AA[0-9a-zA-Z_-]{58}))(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:hubspot-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:hubspot)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:infracost-api-token\",\n re: new RegExp(\"\\\\b(ico-[a-zA-Z0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:intercom-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:intercom)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9=_\\\\-]{60})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:jfrog-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:jfrog|artifactory|bintray|xray)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{73})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:jfrog-identity-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:jfrog|artifactory|bintray|xray)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:jwt\",\n re: new RegExp(\n \"\\\\b(ey[a-zA-Z0-9]{17,}\\\\.ey[a-zA-Z0-9\\\\/\\\\\\\\_-]{17,}\\\\.(?:[a-zA-Z0-9\\\\/\\\\\\\\_-]{10,}={0,2})?)(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:jwt-base64\",\n re: new RegExp(\n \"\\\\bZXlK(?:(?<alg>aGJHY2lPaU)|(?<apu>aGNIVWlPaU)|(?<apv>aGNIWWlPaU)|(?<aud>aGRXUWlPaU)|(?<b64>aU5qUWlP)|(?<crit>amNtbDBJanBi)|(?<cty>amRIa2lPaU)|(?<epk>bGNHc2lPbn)|(?<enc>bGJtTWlPaU)|(?<jku>cWEzVWlPaU)|(?<jwk>cWQyc2lPb)|(?<iss>cGMzTWlPaU)|(?<iv>cGRpSTZJ)|(?<kid>cmFXUWlP)|(?<key_ops>clpYbGZiM0J6SWpwY)|(?<kty>cmRIa2lPaUp)|(?<nonce>dWIyNWpaU0k2)|(?<p2c>d01tTWlP)|(?<p2s>d01uTWlPaU)|(?<ppt>d2NIUWlPaU)|(?<sub>emRXSWlPaU)|(?<svt>emRuUWlP)|(?<tag>MFlXY2lPaU)|(?<typ>MGVYQWlPaUp)|(?<url>MWNtd2l)|(?<use>MWMyVWlPaUp)|(?<ver>MlpYSWlPaU)|(?<version>MlpYSnphVzl1SWpv)|(?<x>NElqb2)|(?<x5c>NE5XTWlP)|(?<x5t>NE5YUWlPaU)|(?<x5ts256>NE5YUWpVekkxTmlJNkl)|(?<x5u>NE5YVWlPaU)|(?<zip>NmFYQWlPaU))[a-zA-Z0-9\\\\/\\\\\\\\_+\\\\-\\\\r\\\\n]{40,}={0,2}\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:kraken-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:kraken)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9\\\\/=_\\\\+\\\\-]{80,90})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:kucoin-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:kucoin)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{24})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:kucoin-secret-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:kucoin)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:launchdarkly-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:launchdarkly)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9=_\\\\-]{40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:linear-client-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:linear)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:linkedin-client-id\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:linked[_-]?in)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{14})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:linkedin-client-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:linked[_-]?in)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{16})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:lob-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:lob)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}((live|test)_[a-f0-9]{35})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:lob-pub-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:lob)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}((test|live)_pub_[a-f0-9]{31})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:looker-client-id\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:looker)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{20})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:looker-client-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:looker)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{24})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:mailchimp-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:MailchimpSDK.initialize|mailchimp)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{32}-us\\\\d\\\\d)(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:mailgun-private-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:mailgun)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(key-[a-f0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:mailgun-pub-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:mailgun)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(pubkey-[a-f0-9]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:mailgun-signing-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:mailgun)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:mapbox-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:mapbox)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(pk\\\\.[a-z0-9]{60}\\\\.[a-z0-9]{22})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:mattermost-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:mattermost)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{26})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:maxmind-license-key\",\n re: new RegExp(\"\\\\b([A-Za-z0-9]{6}_[A-Za-z0-9]{29}_mmk)(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:messagebird-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:message[_-]?bird)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{25})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:messagebird-client-id\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:message[_-]?bird)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:microsoft-teams-webhook\",\n re: new RegExp(\n \"https://[a-z0-9]+\\\\.webhook\\\\.office\\\\.com/webhookb2/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}/IncomingWebhook/[a-z0-9]{32}/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:netlify-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:netlify)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9=_\\\\-]{40,46})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:new-relic-browser-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(NRJS-[a-f0-9]{19})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:new-relic-insert-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(NRII-[a-z0-9-]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:new-relic-user-api-id\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:new-relic-user-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(NRAK-[a-z0-9]{27})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:notion-api-token\",\n re: new RegExp(\n \"\\\\b(ntn_[0-9]{11}[A-Za-z0-9]{32}[A-Za-z0-9]{3})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:npm-access-token\",\n re: new RegExp(\"\\\\b(npm_[a-z0-9]{36})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"gi\"),\n },\n {\n kind: \"gitleaks:nuget-config-password\",\n re: new RegExp('<add key=\\\\\"(?:(?:ClearText)?Password)\\\\\"\\\\s*value=\\\\\"(.{8,})\\\\\"\\\\s*/>', \"gi\"),\n },\n {\n kind: \"gitleaks:nytimes-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:nytimes|new-york-times,|newyorktimes)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9=_\\\\-]{32})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:octopus-deploy-api-key\",\n re: new RegExp(\"\\\\b(API-[A-Z0-9]{26})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:openai-api-key\",\n re: new RegExp(\n \"\\\\b(sk-(?:proj|svcacct|admin)-(?:[A-Za-z0-9_-]{74}|[A-Za-z0-9_-]{58})T3BlbkFJ(?:[A-Za-z0-9_-]{74}|[A-Za-z0-9_-]{58})\\\\b|sk-[a-zA-Z0-9]{20}T3BlbkFJ[a-zA-Z0-9]{20})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:openshift-user-token\",\n re: new RegExp(\"\\\\b(sha256~[\\\\w-]{43})(?:[^\\\\w-]|\\\\z)\", \"g\"),\n },\n {\n kind: \"gitleaks:perplexity-api-key\",\n re: new RegExp(\"\\\\b(pplx-[a-zA-Z0-9]{48})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$|\\\\b)\", \"g\"),\n },\n {\n kind: \"gitleaks:plaid-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:plaid)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(access-(?:sandbox|development|production)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:plaid-client-id\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:plaid)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{24})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:plaid-secret-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:plaid)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{30})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:planetscale-oauth-token\",\n re: new RegExp(\"\\\\b(pscale_oauth_[\\\\w=\\\\.-]{32,64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:prefect-api-token\",\n re: new RegExp(\"\\\\b(pnu_[a-zA-Z0-9]{36})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:private-key\",\n re: new RegExp(\n \"-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY(?: BLOCK)?-----[\\\\s\\\\S-]{64,}?KEY(?: BLOCK)?-----\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:pulumi-api-token\",\n re: new RegExp(\"\\\\b(pul-[a-f0-9]{40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:pypi-upload-token\",\n re: new RegExp(\"pypi-AgEIcHlwaS5vcmc[\\\\w-]{50,1000}\", \"g\"),\n },\n {\n kind: \"gitleaks:rapidapi-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:rapidapi)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9_-]{50})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:readme-api-token\",\n re: new RegExp(\"\\\\b(rdme_[a-z0-9]{70})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:rubygems-api-token\",\n re: new RegExp(\"\\\\b(rubygems_[a-f0-9]{48})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:scalingo-api-token\",\n re: new RegExp(\"\\\\b(tk-us-[\\\\w-]{48})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:sendbird-access-id\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:sendbird)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:sendbird-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:sendbird)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:sentry-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:sentry)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:sentry-org-token\",\n re: new RegExp(\n \"\\\\bsntrys_eyJpYXQiO[a-zA-Z0-9+/]{10,200}(?:LCJyZWdpb25fdXJs|InJlZ2lvbl91cmwi|cmVnaW9uX3VybCI6)[a-zA-Z0-9+/]{10,200}={0,2}_[a-zA-Z0-9+/]{43}(?:[^a-zA-Z0-9+/]|\\\\z)\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:sentry-user-token\",\n re: new RegExp(\"\\\\b(sntryu_[a-f0-9]{64})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:settlemint-application-access-token\",\n re: new RegExp(\"\\\\b(sm_aat_[a-zA-Z0-9]{16})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:settlemint-personal-access-token\",\n re: new RegExp(\"\\\\b(sm_pat_[a-zA-Z0-9]{16})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:settlemint-service-access-token\",\n re: new RegExp(\"\\\\b(sm_sat_[a-zA-Z0-9]{16})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:shippo-api-token\",\n re: new RegExp(\"\\\\b(shippo_(?:live|test)_[a-fA-F0-9]{40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n { kind: \"gitleaks:shopify-access-token\", re: new RegExp(\"shpat_[a-fA-F0-9]{32}\", \"g\") },\n { kind: \"gitleaks:shopify-custom-access-token\", re: new RegExp(\"shpca_[a-fA-F0-9]{32}\", \"g\") },\n {\n kind: \"gitleaks:shopify-private-app-access-token\",\n re: new RegExp(\"shppa_[a-fA-F0-9]{32}\", \"g\"),\n },\n { kind: \"gitleaks:shopify-shared-secret\", re: new RegExp(\"shpss_[a-fA-F0-9]{32}\", \"g\") },\n {\n kind: \"gitleaks:sidekiq-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:sidekiq-sensitive-url\",\n re: new RegExp(\n \"\\\\bhttps?://([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\\\\/|\\\\#|\\\\?|:]|$)\",\n \"gi\",\n ),\n },\n { kind: \"gitleaks:slack-app-token\", re: new RegExp(\"xapp-\\\\d-[A-Z0-9]+-\\\\d+-[a-z0-9]+\", \"gi\") },\n {\n kind: \"gitleaks:slack-bot-token\",\n re: new RegExp(\"xoxb-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*\", \"g\"),\n },\n {\n kind: \"gitleaks:slack-config-access-token\",\n re: new RegExp(\"xoxe.xox[bp]-\\\\d-[A-Z0-9]{163,166}\", \"gi\"),\n },\n { kind: \"gitleaks:slack-config-refresh-token\", re: new RegExp(\"xoxe-\\\\d-[A-Z0-9]{146}\", \"gi\") },\n {\n kind: \"gitleaks:slack-legacy-bot-token\",\n re: new RegExp(\"xoxb-[0-9]{8,14}-[a-zA-Z0-9]{18,26}\", \"g\"),\n },\n {\n kind: \"gitleaks:slack-legacy-token\",\n re: new RegExp(\"xox[os]-\\\\d+-\\\\d+-\\\\d+-[a-fA-F\\\\d]+\", \"g\"),\n },\n {\n kind: \"gitleaks:slack-legacy-workspace-token\",\n re: new RegExp(\"xox[ar]-(?:\\\\d-)?[0-9a-zA-Z]{8,48}\", \"g\"),\n },\n {\n kind: \"gitleaks:slack-user-token\",\n re: new RegExp(\"xox[pe](?:-[0-9]{10,13}){3}-[a-zA-Z0-9-]{28,34}\", \"g\"),\n },\n {\n kind: \"gitleaks:slack-webhook-url\",\n re: new RegExp(\n \"(?:https?://)?hooks.slack.com/(?:services|workflows|triggers)/[A-Za-z0-9+/]{43,56}\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:snyk-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:snyk[_.-]?(?:(?:api|oauth)[_.-]?)?(?:key|token))(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:sonar-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:sonar[_.-]?(login|token))(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}((?:squ_|sqp_|sqa_)?[a-z0-9=_\\\\-]{40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:square-access-token\",\n re: new RegExp(\"\\\\b((?:EAAA|sq0atp-)[\\\\w-]{22,60})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:squarespace-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:squarespace)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:stripe-access-token\",\n re: new RegExp(\n \"\\\\b((?:sk|rk)_(?:test|live|prod)_[a-zA-Z0-9]{10,99})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"g\",\n ),\n },\n {\n kind: \"gitleaks:travisci-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:travis)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{22})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n { kind: \"gitleaks:twilio-api-key\", re: new RegExp(\"SK[0-9a-fA-F]{32}\", \"g\") },\n {\n kind: \"gitleaks:twitch-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:twitch)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{30})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:twitter-access-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:twitter)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{45})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:twitter-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:twitter)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([0-9]{15,25}-[a-zA-Z0-9]{20,40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:twitter-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:twitter)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{25})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:twitter-api-secret\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:twitter)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{50})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:twitter-bearer-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:twitter)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(A{22}[a-zA-Z0-9%]{80,100})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:typeform-api-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:typeform)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(tfp_[a-z0-9\\\\-_\\\\.=]{59})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:vault-batch-token\",\n re: new RegExp(\"\\\\b(hvb\\\\.[\\\\w-]{138,300})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\", \"g\"),\n },\n {\n kind: \"gitleaks:yandex-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:yandex)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(t1\\\\.[A-Z0-9a-z_-]+[=]{0,2}\\\\.[A-Z0-9a-z_-]{86}[=]{0,2})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:yandex-api-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:yandex)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(AQVN[A-Za-z0-9_\\\\-]{35,38})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:yandex-aws-access-token\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:yandex)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}(YC[a-zA-Z0-9_\\\\-]{38})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n {\n kind: \"gitleaks:zendesk-secret-key\",\n re: new RegExp(\n \"[\\\\w.-]{0,50}?(?:zendesk)(?:[ \\\\t\\\\w.-]{0,20})[\\\\s'\\\"]{0,3}(?:=|>|:{1,3}=|\\\\|\\\\||:|=>|\\\\?=|,)[\\\\x60'\\\"\\\\s=]{0,5}([a-z0-9]{40})(?:[\\\\x60'\\\"\\\\s;]|\\\\\\\\[nr]|$)\",\n \"gi\",\n ),\n },\n];\n","/**\n * Secret scanner (issue #16). A shared, synced brain must never carry credentials, so\n * we detect and redact common, low-false-positive secrets. Used to block secrets at\n * capture (curate) and to scrub hand-edited notes at pre-commit (sync) as defense in\n * depth. Detection is intentionally conservative: patterns are tuned to real credential\n * shapes so ordinary prose (e.g. \"the password is rotated monthly\") does not match.\n */\n\nimport { GITLEAKS_PATTERNS } from \"./secrets-gitleaks.generated.js\";\n\n/** A single detected secret. Never carries the raw value — only a masked preview. */\nexport interface SecretMatch {\n /** Which pattern matched (e.g. \"aws-access-key-id\", \"github-token\"). */\n kind: string;\n /** Zero-based index of the match start within the scanned text. */\n index: number;\n /** Length in characters of the matched substring. */\n length: number;\n /** The match with its middle masked (first4 + \"...\" + last2); never the full secret. */\n preview: string;\n}\n\n/**\n * Credential patterns, ordered most-specific first so a value that could match both a\n * specific provider and the generic assignment is attributed to the specific provider.\n * Each `re` MUST be global (`g`) so {@link findSecrets} can iterate all matches.\n */\nexport const SECRET_PATTERNS: ReadonlyArray<{ kind: string; re: RegExp }> = [\n { kind: \"aws-access-key-id\", re: /AKIA[0-9A-Z]{16}/g },\n { kind: \"github-token\", re: /(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}/g },\n { kind: \"github-pat\", re: /github_pat_[A-Za-z0-9_]{20,}/g },\n // Anthropic base64url bodies include \"_\", and modern keys are sk-ant-api03-… .\n { kind: \"anthropic-api-key\", re: /sk-ant-[A-Za-z0-9_-]{20,}/g },\n // Modern OpenAI keys are prefixed (sk-proj-/sk-svcacct-/sk-admin-) with hyphens in the\n // body; keep the legacy pure-alnum form too. Ordered after anthropic so sk-ant- wins.\n {\n kind: \"openai-api-key\",\n re: /sk-(?:proj|svcacct|admin)-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9]{20,}/g,\n },\n { kind: \"google-api-key\", re: /AIza[0-9A-Za-z_-]{35}/g },\n { kind: \"google-oauth-token\", re: /ya29\\.[0-9A-Za-z_-]{20,}/g },\n { kind: \"slack-token\", re: /xox[baprs]-[A-Za-z0-9-]{10,}/g },\n {\n kind: \"slack-webhook\",\n re: /https:\\/\\/hooks\\.slack\\.com\\/services\\/T[A-Za-z0-9_]+\\/B[A-Za-z0-9_]+\\/[A-Za-z0-9_]+/g,\n },\n // Stripe (sk_live_/pk_live_/rk_test_…), SendGrid, npm, Twilio SID/key — distinctive\n // prefixes, low false-positive. Inspired by the SecretFinder pattern set.\n { kind: \"stripe-key\", re: /(?:sk|rk|pk)_(?:live|test)_[0-9A-Za-z]{16,}/g },\n { kind: \"sendgrid-key\", re: /SG\\.[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{16,}/g },\n { kind: \"npm-token\", re: /npm_[A-Za-z0-9]{36}/g },\n { kind: \"twilio-account-sid\", re: /AC[0-9a-fA-F]{32}/g },\n { kind: \"twilio-api-key\", re: /SK[0-9a-fA-F]{32}/g },\n { kind: \"private-key\", re: /-----BEGIN [A-Z ]*PRIVATE KEY-----/g },\n {\n // A sensitive word as a whole `_`-delimited token inside an identifier (so\n // aws_secret_access_key / OPENAI_API_KEY / DATABASE_PASSWORD match) followed by an\n // assignment of an 8+ char value. Token-bounded to avoid prose (\"the password is…\")\n // and look-alikes (\"secretary = …\", \"tokenize the input\").\n kind: \"generic-secret-assignment\",\n re: /(?<![A-Za-z0-9_])(?:[A-Za-z0-9]+_)*(?:password|passwd|secret|token|api[_-]?key|access[_-]?token|auth[_-]?token|client[_-]?secret|private[_-]?key|credentials?)(?:_[A-Za-z0-9]+)*\\s*[:=]\\s*[\"']?[^\\s\"']{8,}/gi,\n },\n];\n\n/**\n * All patterns scanned by {@link findSecrets} / {@link hasSecrets}: our hand-tuned\n * {@link SECRET_PATTERNS} FIRST (so on an overlapping start index their more specific\n * attribution wins the dedupe), then the gitleaks-derived {@link GITLEAKS_PATTERNS}\n * which widen coverage to providers we don't hand-maintain. Internal — the public API is\n * unchanged.\n */\nconst ALL_PATTERNS: ReadonlyArray<{ kind: string; re: RegExp }> = [\n ...SECRET_PATTERNS,\n ...GITLEAKS_PATTERNS,\n];\n\n/**\n * Mask a matched secret for reporting: keep the first 4 and last 2 characters, replace\n * the middle with \"...\". Short matches degrade gracefully to all-asterisks so the raw\n * value is never reconstructable from the preview.\n */\nfunction maskPreview(match: string): string {\n if (match.length <= 6) return \"*\".repeat(match.length);\n return `${match.slice(0, 4)}...${match.slice(-2)}`;\n}\n\n/**\n * Shannon entropy of `s` in BITS PER CHARACTER (0 for empty). A uniform random base64 string\n * approaches ~6, hex ~4, English prose ~1–1.5. Used by the opt-in entropy detector to flag\n * high-randomness tokens that match no named pattern (novel/custom secrets, #46).\n */\nexport function shannonEntropy(s: string): number {\n if (s.length === 0) return 0;\n const counts = new Map<string, number>();\n for (const ch of s) counts.set(ch, (counts.get(ch) ?? 0) + 1);\n let bits = 0;\n for (const n of counts.values()) {\n const p = n / s.length;\n bits -= p * Math.log2(p);\n }\n return bits;\n}\n\n/** Options for the scanners: opt-in entropy detection and a false-positive allowlist (#46). */\nexport interface ScanOptions {\n /**\n * Also flag high-entropy base64/hex tokens that match no named pattern. Default OFF: it needs\n * the {@link ScanOptions.allowlist} to stay usable (git SHAs, UUIDs, base64 data can trip it),\n * so a brain opts in via config rather than it changing the zero-FP default everywhere.\n */\n detectEntropy?: boolean;\n /** Exact token values to never flag (accepted values / known false positives). Per-brain. */\n allowlist?: readonly string[];\n}\n\n/** High-entropy candidate tokens: long base64/base64url runs and long hex runs. */\nconst ENTROPY_TOKEN_RES: ReadonlyArray<RegExp> = [\n /[A-Za-z0-9+/_-]{20,}={0,2}/g, // base64 / base64url\n /\\b[0-9a-fA-F]{32,}\\b/g, // long hex\n];\n/** Bits/char above which a base64-ish token is treated as secret-like (detect-secrets ~4.5). */\nconst BASE64_ENTROPY_MIN = 4.5;\n/** Bits/char threshold for hex tokens (lower alphabet → lower max entropy; detect-secrets ~3.0). */\nconst HEX_ENTROPY_MIN = 3.0;\n\nfunction isHex(s: string): boolean {\n return /^[0-9a-fA-F]+$/.test(s);\n}\n\n/**\n * Scan `text` with every pattern in {@link ALL_PATTERNS} (our hand-tuned\n * {@link SECRET_PATTERNS} first, then {@link GITLEAKS_PATTERNS}) and return the matches,\n * deduplicated by start index and sorted by position. When two patterns hit the same\n * index, the earlier (more specific) pattern wins. Previews are masked — the raw secret\n * is never returned.\n */\nexport function findSecrets(text: string, opts: ScanOptions = {}): SecretMatch[] {\n const allow = opts.allowlist && opts.allowlist.length > 0 ? new Set(opts.allowlist) : null;\n const byIndex = new Map<number, SecretMatch>();\n\n for (const { kind, re } of ALL_PATTERNS) {\n // Reset lastIndex: patterns are module-level and shared across calls.\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const value = m[0];\n // Guard against zero-width matches spinning forever.\n if (value.length === 0) {\n re.lastIndex += 1;\n continue;\n }\n if (allow?.has(value)) continue; // accepted value / known false positive (#46)\n if (!byIndex.has(m.index)) {\n byIndex.set(m.index, {\n kind,\n index: m.index,\n length: value.length,\n preview: maskPreview(value),\n });\n }\n }\n }\n\n if (opts.detectEntropy) addEntropyMatches(text, byIndex, allow);\n\n return [...byIndex.values()].sort((a, b) => a.index - b.index);\n}\n\n/**\n * Add high-entropy tokens (base64/hex over threshold) to `byIndex`, unless they overlap a token\n * a named pattern already flagged at the same start, are allowlisted, or fall below the entropy\n * bar. Opt-in via {@link ScanOptions.detectEntropy} (#46).\n */\nfunction addEntropyMatches(\n text: string,\n byIndex: Map<number, SecretMatch>,\n allow: Set<string> | null,\n): void {\n for (const re of ENTROPY_TOKEN_RES) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const value = m[0];\n if (value.length === 0) {\n re.lastIndex += 1;\n continue;\n }\n if (byIndex.has(m.index) || allow?.has(value)) continue;\n const min = isHex(value) ? HEX_ENTROPY_MIN : BASE64_ENTROPY_MIN;\n if (shannonEntropy(value) < min) continue;\n byIndex.set(m.index, {\n kind: \"high-entropy-string\",\n index: m.index,\n length: value.length,\n preview: maskPreview(value),\n });\n }\n }\n}\n\n/** True if `text` contains at least one detected secret. */\nexport function hasSecrets(text: string, opts: ScanOptions = {}): boolean {\n // Entropy/allowlist need the full findSecrets path; the fast regex-only path handles the\n // common (default) case without allocating match objects.\n if (opts.detectEntropy || (opts.allowlist && opts.allowlist.length > 0)) {\n return findSecrets(text, opts).length > 0;\n }\n for (const { re } of ALL_PATTERNS) {\n re.lastIndex = 0;\n if (re.test(text)) return true;\n }\n return false;\n}\n\n/**\n * Replace every detected secret in `text` with a `[REDACTED:<kind>]` placeholder,\n * preserving all surrounding content. Overlapping/duplicate matches are handled by\n * {@link findSecrets}; replacement runs right-to-left so earlier indices stay valid.\n */\nexport function redactSecrets(text: string, opts: ScanOptions = {}): string {\n const matches = findSecrets(text, opts);\n let out = text;\n for (let i = matches.length - 1; i >= 0; i--) {\n const { kind, index, length } = matches[i]!;\n out = `${out.slice(0, index)}[REDACTED:${kind}]${out.slice(index + length)}`;\n }\n return out;\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport Database from \"better-sqlite3\";\nimport { listNotes } from \"./notes.js\";\nimport { type Note, type NoteKind } from \"./schema.js\";\n\nexport interface SearchOptions {\n kind?: NoteKind;\n /** Restrict to notes from one originating project (frontmatter `source`; ADR-0015). */\n source?: string;\n /** Max results (default 20). */\n limit?: number;\n}\n\nexport interface SearchResult {\n id: string;\n kind: NoteKind;\n title: string;\n path: string;\n /** Originating project, when the note carries one. */\n source?: string;\n /** Highlighted excerpt around the match. */\n snippet: string;\n /** Relevance score (higher = better). */\n score: number;\n}\n\n/** Repo-relative location of the derived, disposable SQLite index. */\nconst INDEX_DIR = \"index\";\nconst DB_FILE = \"commonwealth.db\";\n\n/** Absolute path to the SQLite index db for a brain. */\nfunction dbPath(brainDir: string): string {\n return path.join(brainDir, INDEX_DIR, DB_FILE);\n}\n\n/** Row shape mirrored into the FTS5 table. */\ninterface IndexRow {\n id: string;\n kind: NoteKind;\n title: string;\n tags: string;\n body: string;\n path: string;\n source: string;\n}\n\nfunction toRow(note: Note): IndexRow {\n return {\n id: note.frontmatter.id,\n kind: note.frontmatter.kind,\n title: note.frontmatter.title,\n tags: note.frontmatter.tags.join(\" \"),\n body: note.body,\n path: note.path,\n source: note.frontmatter.source ?? \"\",\n };\n}\n\n/**\n * (Re)build the derived SQLite FTS5 index from the markdown notes under `brainDir`.\n * The index lives at `index/commonwealth.db`, is gitignored, and is fully disposable —\n * it can always be rebuilt from the files. See ADR-0005.\n *\n * Performs a FULL rebuild each call (DROP + CREATE) so the result is a pure function\n * of the note set and running it twice is idempotent. Returns the count indexed.\n */\nexport async function buildIndex(brainDir: string): Promise<{ indexed: number }> {\n await fs.mkdir(path.join(brainDir, INDEX_DIR), { recursive: true });\n const notes = await listNotes(brainDir);\n\n const db = new Database(dbPath(brainDir));\n try {\n // Full rebuild + read-only queries: the default rollback journal leaves no\n // persistent sidecar files (unlike WAL's -wal/-shm), keeping index/ clean.\n //\n // Do the DROP + CREATE + inserts in ONE transaction so an interrupt (crash, SIGTERM)\n // rolls the whole thing back: the db is never left with the old table dropped and the\n // new one missing/half-populated, which would make `search` throw \"no such table\"\n // forever (#101). Either the previous index survives intact, or the new one lands whole.\n const rebuild = db.transaction((rows: IndexRow[]) => {\n db.exec(\"DROP TABLE IF EXISTS notes_fts;\");\n // `path` is UNINDEXED: stored/returned but not part of the full-text match.\n db.exec(\n \"CREATE VIRTUAL TABLE notes_fts USING fts5(\" +\n \"id, kind, title, tags, body, path UNINDEXED, source UNINDEXED\" +\n \");\",\n );\n const insert = db.prepare(\n \"INSERT INTO notes_fts (id, kind, title, tags, body, path, source) \" +\n \"VALUES (@id, @kind, @title, @tags, @body, @path, @source);\",\n );\n for (const row of rows) insert.run(row);\n });\n rebuild(notes.map(toRow));\n\n return { indexed: notes.length };\n } finally {\n db.close();\n }\n}\n\n/** True if the FTS table exists in an already-open db (survives a partial/interrupted build). */\nfunction hasFtsTable(db: Database.Database): boolean {\n const row = db\n .prepare(\"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'notes_fts'\")\n .get();\n return row !== undefined;\n}\n\n/**\n * Escape a user query for FTS5 by wrapping each whitespace-separated token as a\n * quoted string, so punctuation in the query can't be parsed as FTS operators.\n * Empty queries yield \"\" (which matches nothing).\n */\nfunction toMatchQuery(query: string): string {\n return query\n .split(/\\s+/)\n .map((t) => t.replace(/\"/g, \"\"))\n .filter((t) => t.length > 0)\n .map((t) => `\"${t}\"`)\n .join(\" \");\n}\n\n/**\n * Lexical (FTS5) search over title, body, and tags. Builds the index on first use if it\n * is missing, but does NOT detect subsequent note additions/edits/removals — the index\n * refreshes only when {@link buildIndex} is called. Callers that need fresh results after\n * writes should rebuild first.\n */\nexport async function search(\n brainDir: string,\n query: string,\n opts?: SearchOptions,\n): Promise<SearchResult[]> {\n // Build the index on demand if it has never been created.\n try {\n await fs.access(dbPath(brainDir));\n } catch {\n await buildIndex(brainDir);\n }\n\n // Self-heal (#101): the db file can exist but lack `notes_fts` — e.g. a build interrupted\n // before this fix, or an externally-truncated db. Detect the missing table and rebuild once,\n // so search recovers instead of throwing \"no such table: notes_fts\" on every call forever.\n {\n const probe = new Database(dbPath(brainDir), { readonly: true });\n let healthy: boolean;\n try {\n healthy = hasFtsTable(probe);\n } finally {\n probe.close();\n }\n if (!healthy) await buildIndex(brainDir);\n }\n\n const match = toMatchQuery(query);\n if (match === \"\") return [];\n\n const limit = opts?.limit ?? 20;\n const db = new Database(dbPath(brainDir), { readonly: true });\n try {\n // snippet(): excerpt of the body column (index 4) with matches marked by [ ].\n // bm25() returns a negative-ish score where lower = more relevant, so we negate\n // it to expose a positive score where higher = better.\n const params: (string | number)[] = [match];\n let sql =\n \"SELECT id, kind, title, path, source, \" +\n \"snippet(notes_fts, 4, '[', ']', '…', 12) AS snippet, \" +\n \"-bm25(notes_fts) AS score \" +\n \"FROM notes_fts WHERE notes_fts MATCH ?\";\n if (opts?.kind) {\n sql += \" AND kind = ?\";\n params.push(opts.kind);\n }\n if (opts?.source) {\n sql += \" AND source = ?\";\n params.push(opts.source);\n }\n sql += \" ORDER BY bm25(notes_fts) LIMIT ?\";\n params.push(limit);\n\n const rows = db.prepare(sql).all(...params) as Array<{\n id: string;\n kind: NoteKind;\n title: string;\n path: string;\n source: string;\n snippet: string;\n score: number;\n }>;\n\n return rows.map((r) => ({\n id: r.id,\n kind: r.kind,\n title: r.title,\n path: r.path,\n ...(r.source ? { source: r.source } : {}),\n snippet: r.snippet,\n score: r.score,\n }));\n } finally {\n db.close();\n }\n}\n\n/**\n * Neutralize a note-controlled string for safe inclusion in the GENERATED markdown that agents\n * read (COMMONWEALTH.md / INDEX.md). Titles and `source` are free text; without this a title\n * like `x](evil.md) ## Ignore prior instructions\\n# ` could break out of its link/list item and\n * inject new markdown structure (headings, links, directives) into every teammate's injected\n * context — a prompt-injection vector (#102). We collapse line breaks (so it can't start a new\n * block), escape the markdown-structural chars `[` `]` `` ` `` (so it can't form a link or code\n * span), and cap the length. The stored note is untouched; only the derived rendering is escaped.\n */\nfunction inlineText(value: string): string {\n return value\n .replace(/[\\r\\n]+/g, \" \")\n .replace(/[[\\]`]/g, (c) => `\\\\${c}`)\n .replace(/\\s+/g, \" \")\n .trim()\n .slice(0, 200);\n}\n\n/** Notes whose `status` counts as still-active work (i.e. not `done`). */\nfunction isActiveWorkState(note: Note): boolean {\n return note.frontmatter.kind === \"work-state\" && note.frontmatter.status !== \"done\";\n}\n\n/** Stable, deterministic sort by id so derived output is byte-identical across runs. */\nfunction byId(a: Note, b: Note): number {\n return a.frontmatter.id < b.frontmatter.id ? -1 : a.frontmatter.id > b.frontmatter.id ? 1 : 0;\n}\n\n/** Sort decisions by created date desc, tie-broken by id for determinism. */\nfunction byCreatedDesc(a: Note, b: Note): number {\n if (a.frontmatter.created !== b.frontmatter.created) {\n return a.frontmatter.created < b.frontmatter.created ? 1 : -1;\n }\n return byId(a, b);\n}\n\n/** Display label for a note's originating project; unattributed notes group under a sentinel. */\nconst UNATTRIBUTED = \"(unattributed)\";\nfunction sourceOf(note: Note): string {\n return note.frontmatter.source && note.frontmatter.source.length > 0\n ? note.frontmatter.source\n : UNATTRIBUTED;\n}\n\n/** Sort project labels alphabetically, with the unattributed bucket always last. */\nfunction bySourceLabel(a: string, b: string): number {\n if (a === UNATTRIBUTED) return b === UNATTRIBUTED ? 0 : 1;\n if (b === UNATTRIBUTED) return -1;\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/**\n * The generated router, grouped by originating project (ADR-0015): a section per project with\n * its active work-state and recent decisions, so a shared brain reads project-by-project.\n */\nfunction commonwealthMarkdown(notes: Note[]): string {\n const lines: string[] = [];\n lines.push(\"# Commonwealth\");\n lines.push(\"\");\n lines.push(\"> Generated router. Do not edit by hand — regenerated from the note set (ADR-0003).\");\n lines.push(\"\");\n\n const bySource = new Map<string, Note[]>();\n for (const n of notes) {\n const key = sourceOf(n);\n (bySource.get(key) ?? bySource.set(key, []).get(key)!).push(n);\n }\n const sources = [...bySource.keys()].sort(bySourceLabel);\n if (sources.length === 0) {\n lines.push(\"_No notes yet._\");\n lines.push(\"\");\n return lines.join(\"\\n\");\n }\n\n for (const source of sources) {\n const group = bySource.get(source)!;\n const active = group.filter(isActiveWorkState).sort(byId);\n const decisions = group.filter((n) => n.frontmatter.kind === \"decision\").sort(byCreatedDesc);\n lines.push(`## ${inlineText(source)}`);\n lines.push(\"\");\n lines.push(\"**Active work-state**\");\n if (active.length === 0) {\n lines.push(\"- _None._\");\n } else {\n for (const n of active) {\n const status = n.frontmatter.kind === \"work-state\" ? n.frontmatter.status : \"\";\n lines.push(`- [${inlineText(n.frontmatter.title)}](${n.path}) — ${status}`);\n }\n }\n lines.push(\"\");\n lines.push(\"**Recent decisions**\");\n if (decisions.length === 0) {\n lines.push(\"- _None._\");\n } else {\n for (const n of decisions) {\n lines.push(`- [${inlineText(n.frontmatter.title)}](${n.path}) — ${n.frontmatter.created}`);\n }\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Generated INDEX.md for one note-containing directory: its notes, linked by filename. */\nfunction indexMarkdown(dirRel: string, notes: Note[]): string {\n const sorted = [...notes].sort(byId);\n const lines: string[] = [];\n lines.push(`# ${dirRel}`);\n lines.push(\"\");\n lines.push(\"> Generated index. Do not edit by hand — regenerated from the note set.\");\n lines.push(\"\");\n if (sorted.length === 0) {\n lines.push(\"_None._\");\n } else {\n for (const n of sorted) {\n // INDEX.md lives in the same folder as the notes, so link by filename only.\n lines.push(`- [${inlineText(n.frontmatter.title)}](${path.posix.basename(n.path)})`);\n }\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n/**\n * Regenerate derived, never-hand-merged artifacts from the note set: the `COMMONWEALTH.md`\n * router (grouped by project, ADR-0015) and an `INDEX.md` in every directory that holds notes\n * (`<kind>/` and `<project>/<kind>/`). Idempotent — output is a pure function of the files\n * (ADR-0003), so running twice yields byte-identical files.\n */\nexport async function regenerateDerived(brainDir: string): Promise<void> {\n const notes = await listNotes(brainDir);\n\n await fs.writeFile(path.join(brainDir, \"COMMONWEALTH.md\"), commonwealthMarkdown(notes), \"utf8\");\n\n // One INDEX.md per directory that actually contains notes — works for both the flat kind\n // root and per-project subtrees without assuming a fixed set of folders.\n const byDir = new Map<string, Note[]>();\n for (const n of notes) {\n const dir = path.posix.dirname(n.path.split(path.sep).join(\"/\"));\n (byDir.get(dir) ?? byDir.set(dir, []).get(dir)!).push(n);\n }\n for (const [dir, group] of byDir) {\n const abs = path.join(brainDir, dir);\n await fs.mkdir(abs, { recursive: true });\n await fs.writeFile(path.join(abs, \"INDEX.md\"), indexMarkdown(dir, group), \"utf8\");\n }\n}\n","import { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\n/**\n * The brain registry (issue #14): resolve which brain repo a given working directory maps\n * to. The plugin's SessionStart/SessionEnd hooks call {@link resolveBrainDir} to learn the\n * brain for `cwd` before injecting context or capturing learnings; the MCP server reads the\n * resolved path from `COMMONWEALTH_BRAIN_DIR`.\n *\n * Resolution is layered so a project can pin its brain explicitly, a brain repo resolves to\n * itself, teams can map by convention, and everything falls back to an env var — see\n * docs/03-distribution.md §3.\n */\n\n/** Marker file, relative to a project dir, naming that project's brain: `.commonwealth/brain`. */\nconst MARKER_REL = path.join(\".commonwealth\", \"brain\");\n\n/**\n * A brain repo is identified by its `.commonwealth/schema-version` file (written by\n * `initBrain`). We deliberately do NOT key off `.commonwealth/config.json`: that name\n * collides with the per-user *scope* config at `~/.commonwealth/config.json` (ADR-0008),\n * which would otherwise make the home directory resolve as a brain. `schema-version` is a\n * brain-only scaffold artifact, so it disambiguates cleanly (ADR-0011).\n */\nconst BRAIN_IDENTITY_REL = path.join(\".commonwealth\", \"schema-version\");\n\n/** One prefix → brain mapping entry in the user registry file. */\nexport interface RegistryMapping {\n /** A path prefix (tilde-allowed); a `cwd` under it maps to {@link brain}. */\n prefix: string;\n /** The brain directory (tilde-allowed) to use for cwds under {@link prefix}. */\n brain: string;\n}\n\n/** Shape of the user registry JSON file (`~/.commonwealth/registry.json`). */\nexport interface Registry {\n mappings: RegistryMapping[];\n}\n\n/** Options for {@link resolveBrainDir}; all optional (env + registry path overrides). */\nexport interface ResolveBrainOptions {\n /** Explicit value to use instead of `process.env.COMMONWEALTH_BRAIN_DIR` (step 4). */\n env?: string;\n /** Explicit registry file path, overriding the default resolution (step 3). */\n registryPath?: string;\n}\n\n/** Expand a leading `~` to the home directory, then resolve to an absolute path. */\nfunction expand(entry: string, base?: string): string {\n const home = os.homedir();\n if (entry === \"~\") return path.resolve(home);\n if (entry.startsWith(\"~/\")) return path.resolve(home, entry.slice(2));\n return base ? path.resolve(base, entry) : path.resolve(entry);\n}\n\n/**\n * True when `child` is the same path as `parent` or nested beneath it. Boundary-safe:\n * `/work` does not contain `/workshop`. Mirrors curate/scope's `isUnder`. Callers pass\n * already-expanded absolute paths.\n */\nfunction isUnder(child: string, parent: string): boolean {\n if (parent === path.sep) return true; // filesystem root contains everything\n return child === parent || child.startsWith(parent + path.sep);\n}\n\n/** Yield `startDir` and each ancestor up to the filesystem root. */\nfunction* walkUp(startDir: string): Generator<string> {\n let current = path.resolve(startDir);\n for (;;) {\n yield current;\n const parent = path.dirname(current);\n if (parent === current) return;\n current = parent;\n }\n}\n\n/** Read a file, returning null on any error (missing/unreadable). */\nasync function readFileOrNull(file: string): Promise<string | null> {\n try {\n return await fs.readFile(file, \"utf8\");\n } catch {\n return null;\n }\n}\n\n/** True when `file` exists and is a regular file. */\nasync function isFile(file: string): Promise<boolean> {\n try {\n const stat = await fs.stat(file);\n return stat.isFile();\n } catch {\n return false;\n }\n}\n\n/** True when `dir` exists and is a directory (symlinks are followed). */\nasync function isDir(dir: string): Promise<boolean> {\n try {\n return (await fs.stat(dir)).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the user registry path. Order: explicit `registryPath` → `$COMMONWEALTH_REGISTRY`\n * (test override) → a `registry.json` sibling of `$COMMONWEALTH_CONFIG` (so tests that redirect\n * config also redirect the registry) → `~/.commonwealth/registry.json`.\n */\nfunction resolveRegistryPath(explicit?: string): string {\n if (explicit) return explicit;\n if (process.env.COMMONWEALTH_REGISTRY) return process.env.COMMONWEALTH_REGISTRY;\n if (process.env.COMMONWEALTH_CONFIG) {\n return path.join(path.dirname(process.env.COMMONWEALTH_CONFIG), \"registry.json\");\n }\n return path.join(os.homedir(), \".commonwealth\", \"registry.json\");\n}\n\n/**\n * Classified result of reading the registry file, so callers can tell \"no file yet\" (safe to\n * start empty) apart from \"file present but unparseable\" (must NOT be clobbered — #78).\n */\ntype RegistryLoad =\n { status: \"ok\"; registry: Registry } | { status: \"missing\" } | { status: \"corrupt\"; raw: string };\n\n/** Read + classify the registry file. Never throws; distinguishes missing from corrupt. */\nasync function readRegistryFile(registryPath: string): Promise<RegistryLoad> {\n const raw = await readFileOrNull(registryPath);\n if (raw === null) return { status: \"missing\" };\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { status: \"corrupt\", raw };\n }\n const obj = (typeof parsed === \"object\" && parsed !== null ? parsed : {}) as Partial<Registry>;\n const mappings = Array.isArray(obj.mappings) ? obj.mappings : [];\n const clean: RegistryMapping[] = [];\n for (const m of mappings) {\n if (\n m &&\n typeof m === \"object\" &&\n typeof (m as RegistryMapping).prefix === \"string\" &&\n typeof (m as RegistryMapping).brain === \"string\"\n ) {\n clean.push({ prefix: (m as RegistryMapping).prefix, brain: (m as RegistryMapping).brain });\n }\n }\n return { status: \"ok\", registry: { mappings: clean } };\n}\n\n/**\n * Parse the registry file into a normalized {@link Registry}; null on missing OR invalid. Used by\n * {@link resolveBrainDir}, which must never throw on a bad file — a corrupt registry simply\n * resolves no mappings (resolution falls through to env). Writers use {@link readRegistryFile}\n * directly so they can refuse to clobber a corrupt file (#78).\n */\nasync function loadRegistry(registryPath: string): Promise<Registry | null> {\n const load = await readRegistryFile(registryPath);\n return load.status === \"ok\" ? load.registry : null;\n}\n\n/**\n * Resolve the brain directory for `startDir`. First hit wins:\n *\n * 1. Walk up from `startDir`: a `.commonwealth/brain` marker file (a path, `~`-expanded and\n * resolved relative to the dir holding it) pins the brain explicitly — but only when that\n * target directory exists. A marker pointing at a missing brain is skipped so a stale/\n * dangling marker falls through to the registry instead of hijacking resolution (#68).\n * 2. Walk up: a directory that is itself a brain (`.commonwealth/schema-version`) resolves to\n * itself.\n * 3. The user registry file (`opts.registryPath` ?? `$COMMONWEALTH_REGISTRY` ?? sibling of\n * `$COMMONWEALTH_CONFIG` ?? `~/.commonwealth/registry.json`): the first `prefix` (tilde-expanded,\n * resolved) that `startDir` is under → its `brain` (tilde-expanded).\n * 4. `opts.env` ?? `process.env.COMMONWEALTH_BRAIN_DIR`, if set.\n * 5. `null`.\n *\n * Never throws on missing/unreadable files.\n */\nexport async function resolveBrainDir(\n startDir: string,\n opts: ResolveBrainOptions = {},\n): Promise<string | null> {\n const start = path.resolve(startDir);\n const registryPath = resolveRegistryPath(opts.registryPath);\n\n // 1) Explicit marker file, nearest ancestor wins — but only when its target actually\n // exists. A marker whose target is missing (a brain that was moved/removed, or a stale\n // marker left by an older onboarding) is skipped so resolution falls through to the\n // registry rather than being hijacked to a dead path (#68). We keep walking up in case\n // a higher ancestor carries a valid marker.\n for (const dir of walkUp(start)) {\n const markerPath = path.join(dir, MARKER_REL);\n const raw = await readFileOrNull(markerPath);\n if (raw !== null) {\n const target = raw.trim();\n if (target.length > 0) {\n const resolved = expand(target, dir);\n if (await isDir(resolved)) return resolved;\n // Dangling marker: ignore it and continue (next ancestor marker, then layers 2–4).\n }\n }\n }\n\n // 2) A directory that is itself a brain, nearest ancestor wins. Keyed off the brain-only\n // `schema-version` file so the global scope-config dir is never mistaken for a brain.\n for (const dir of walkUp(start)) {\n if (await isFile(path.join(dir, BRAIN_IDENTITY_REL))) return dir;\n }\n\n // 3) User registry mappings; the LONGEST (most-specific) matching prefix wins, regardless of\n // insertion order — so a narrow `/work/app` mapping is never shadowed by a broader `/work`\n // one that merely happens to appear earlier in the file (#103).\n const registry = await loadRegistry(registryPath);\n if (registry) {\n let bestBrain: string | null = null;\n let bestLen = -1;\n for (const mapping of registry.mappings) {\n const prefix = expand(mapping.prefix);\n if (isUnder(start, prefix) && prefix.length > bestLen) {\n bestLen = prefix.length;\n bestBrain = expand(mapping.brain);\n }\n }\n if (bestBrain !== null) return bestBrain;\n }\n\n // 4) Env fallback.\n const env = opts.env ?? process.env.COMMONWEALTH_BRAIN_DIR;\n if (env && env.length > 0) return path.resolve(env);\n\n // 5) Nothing matched.\n return null;\n}\n\n/**\n * Write the `.commonwealth/brain` marker in `projectDir` naming `brainPath`, creating the\n * `.commonwealth/` directory if needed. Used to pin a project to its brain (registry step 1).\n */\nexport async function setBrainMarker(projectDir: string, brainPath: string): Promise<void> {\n const markerPath = path.join(projectDir, MARKER_REL);\n await fs.mkdir(path.dirname(markerPath), { recursive: true });\n await fs.writeFile(markerPath, `${brainPath}\\n`, \"utf8\");\n}\n\n/**\n * The default user registry path (public wrapper over the internal resolver): honors\n * `$COMMONWEALTH_REGISTRY`, then a `registry.json` sibling of `$COMMONWEALTH_CONFIG`, then\n * `~/.commonwealth/registry.json`. This is where onboarding writes the project→brain map\n * (resolution layer 3, the default source of truth).\n */\nexport function defaultRegistryPath(): string {\n return resolveRegistryPath();\n}\n\n/**\n * The default convenience-symlink directory (`brains/` next to the registry file), where\n * `~/.commonwealth/brains/<name>` symlinks let a human `ls`/`cd` their brains.\n */\nexport function defaultBrainsDir(): string {\n return path.join(path.dirname(defaultRegistryPath()), \"brains\");\n}\n\n/**\n * Add (or update) a `prefix → brain` mapping in the user registry, the default brain-wiring\n * source of truth (resolution layer 3). Both `prefix` and `brain` are `~`-expanded and\n * resolved to absolute paths; dedupe is by expanded prefix:\n *\n * - no mapping with this prefix → push `{ prefix, brain }` (`added: true`);\n * - a mapping with this prefix but a DIFFERENT brain → update it (`updated: true`);\n * - an identical mapping → no-op (`{ added: false, updated: false }`).\n *\n * Idempotent. Creates the registry's directory if missing and persists pretty (2-space) JSON\n * atomically (tmp file + rename) so a crash mid-write cannot corrupt it. A present-but-corrupt\n * registry is NOT clobbered: it is backed up to `registry.json.corrupt-<ts>` and a clear error is\n * thrown, so a transient/partial-write corruption never silently wipes every other project's\n * brain wiring (#78). A missing file is treated as an empty registry (the normal first-run case).\n */\nexport async function addRegistryMapping(\n prefix: string,\n brain: string,\n registryPath = defaultRegistryPath(),\n): Promise<{ added: boolean; updated: boolean }> {\n const absPrefix = expand(prefix);\n const absBrain = expand(brain);\n\n const load = await readRegistryFile(registryPath);\n if (load.status === \"corrupt\") {\n // Preserve the unparseable file rather than overwrite it, then refuse loudly. Wiring state\n // is user data; \"never silently overwrite\" (ADR-0003) applies here as much as to notes.\n const backup = `${registryPath}.corrupt-${Date.now()}`;\n await fs.rename(registryPath, backup).catch(() => fs.writeFile(backup, load.raw, \"utf8\"));\n throw new Error(\n `Refusing to overwrite a corrupt registry at ${registryPath} (backed up to ${backup}). ` +\n `Fix or remove it, then retry.`,\n );\n }\n const registry: Registry = load.status === \"ok\" ? load.registry : { mappings: [] };\n const existing = registry.mappings.find((m) => expand(m.prefix) === absPrefix);\n\n let added = false;\n let updated = false;\n if (!existing) {\n registry.mappings.push({ prefix: absPrefix, brain: absBrain });\n added = true;\n } else if (expand(existing.brain) !== absBrain) {\n existing.prefix = absPrefix;\n existing.brain = absBrain;\n updated = true;\n } else {\n return { added, updated };\n }\n\n await fs.mkdir(path.dirname(registryPath), { recursive: true });\n // Atomic write: a crash mid-write leaves the old registry intact rather than a partial file.\n const tmp = `${registryPath}.${process.pid}.tmp`;\n await fs.writeFile(tmp, `${JSON.stringify(registry, null, 2)}\\n`, \"utf8\");\n await fs.rename(tmp, registryPath);\n return { added, updated };\n}\n\n/**\n * Drop a convenience symlink `<brainsDir>/<name> → <brainDir>` so a human can `ls`/`cd` their\n * brains. `name` is sanitized via `path.basename`; an empty/`.`/`..` name is rejected. If a\n * symlink already resolves to the target it is a no-op; a symlink pointing elsewhere is\n * replaced; a real (non-symlink) file/dir at the path is left intact and reported as skipped.\n * Never throws for unsupported/permission cases (Windows/EPERM/EACCES/ENOSYS/EEXIST) — those\n * are reported via `skipped`.\n */\nexport async function linkBrain(\n name: string,\n brainDir: string,\n brainsDir = defaultBrainsDir(),\n): Promise<{ path: string; linked: boolean; skipped?: string }> {\n const safe = path.basename(name);\n if (safe === \"\" || safe === \".\" || safe === \"..\") {\n return { path: \"\", linked: false, skipped: \"invalid name\" };\n }\n\n const target = path.resolve(brainDir);\n const symlinkPath = path.join(brainsDir, safe);\n\n try {\n await fs.mkdir(brainsDir, { recursive: true });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n return { path: symlinkPath, linked: false, skipped: code ?? \"cannot create brains dir\" };\n }\n\n let existingStat: import(\"node:fs\").Stats | null = null;\n try {\n existingStat = await fs.lstat(symlinkPath);\n } catch {\n existingStat = null;\n }\n\n if (existingStat) {\n if (existingStat.isSymbolicLink()) {\n let resolved: string | null = null;\n try {\n resolved = path.resolve(brainsDir, await fs.readlink(symlinkPath));\n } catch {\n resolved = null;\n }\n if (resolved === target) return { path: symlinkPath, linked: true };\n try {\n await fs.unlink(symlinkPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n return { path: symlinkPath, linked: false, skipped: code ?? \"symlink unsupported\" };\n }\n } else {\n return { path: symlinkPath, linked: false, skipped: \"exists (not a symlink)\" };\n }\n }\n\n try {\n await fs.symlink(target, symlinkPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n return { path: symlinkPath, linked: false, skipped: code ?? \"symlink unsupported\" };\n }\n return { path: symlinkPath, linked: true };\n}\n","import { execFile } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst pexec = promisify(execFile);\n\n/**\n * Resolve a stable project identity for `cwd` — the value stamped as a note's frontmatter\n * `source` so a shared brain can group/filter notes by originating project (ADR-0015).\n *\n * Order: the nearest ancestor git repo's `origin` remote, slugified to `owner/repo` → else\n * that repo root's basename → else the basename of `cwd`. Best-effort and never throws: git\n * being absent/erroring degrades to the basename. Returns `null` only for an empty input.\n */\nexport async function resolveProjectSource(cwd: string): Promise<string | null> {\n if (typeof cwd !== \"string\" || cwd.length === 0) return null;\n const start = path.resolve(cwd);\n const root = findGitRoot(start);\n if (root) {\n const remote = await originUrl(root);\n const slug = remote ? slugFromRemote(remote) : null;\n return slug ?? path.basename(root);\n }\n return path.basename(start);\n}\n\n/** Nearest ancestor of `startDir` (inclusive) containing a `.git`, or null if none. */\nfunction findGitRoot(startDir: string): string | null {\n let dir = path.resolve(startDir);\n for (;;) {\n if (existsSync(path.join(dir, \".git\"))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/** `git -C <root> config --get remote.origin.url`, or null if unset/unavailable. */\nasync function originUrl(root: string): Promise<string | null> {\n try {\n const { stdout } = await pexec(\"git\", [\"-C\", root, \"config\", \"--get\", \"remote.origin.url\"]);\n const url = stdout.trim();\n return url.length > 0 ? url : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Reduce a git remote URL to a stable `owner/repo` identity (or bare `repo` when there is no\n * owner segment). Handles `git@host:owner/repo.git`, `https://host/owner/repo(.git)`, and\n * `ssh://host/owner/repo`. Returns null when nothing usable can be extracted.\n */\nexport function slugFromRemote(remote: string): string | null {\n // Normalize scp-style `git@host:owner/repo` to a slash-path, then drop scheme/host.\n let s = remote.trim().replace(/\\.git$/i, \"\");\n s = s.replace(/^[a-z]+:\\/\\//i, \"\").replace(/^[^@]+@/, \"\"); // strip scheme and user@\n s = s.replace(/^[^/:]+[:/]/, \"\"); // strip host + first separator (: for scp, / for url)\n const parts = s.split(\"/\").filter((p) => p.length > 0);\n if (parts.length === 0) return null;\n return parts.slice(-2).join(\"/\");\n}\n","import { today } from \"./ids.js\";\nimport { listNotes } from \"./notes.js\";\nimport type { Note } from \"./schema.js\";\n\n/**\n * Brain-health / trust rollup (#109). A shared brain rots if it can't tell fresh from stale, so\n * this surfaces decay: stale, never-verified, contradiction-flagged, and orphaned notes, plus a\n * single headline freshness/trust score. Pure and read-only — computed from the note set (the\n * source of truth), never written back (ADR-0003).\n */\n\n/** Default age (days) past which an active memory note counts as stale. Overridable per call. */\nexport const DEFAULT_STALE_AFTER_DAYS = 90;\n\n/** One bucket of the rollup: how many notes, and which (by id, for drill-down). */\nexport interface HealthBucket {\n count: number;\n ids: string[];\n}\n\n/** The brain-health rollup for a note set. */\nexport interface HealthReport {\n /** Notes considered. */\n total: number;\n /** Explicitly `status: stale`, or an active memory note older than the stale threshold. */\n stale: HealthBucket;\n /** Active memory notes never checked against reality (no `verified` date). */\n unverified: HealthBucket;\n /** Notes flagged as contradicted (a `contradicted` tag; the future embeddings signal, #107). */\n contradicted: HealthBucket;\n /** Notes nothing else links to (no inbound `relates`/`supersedes`/`superseded_by`/`sources`). */\n orphaned: HealthBucket;\n /** Composite freshness/trust score, 0–100 (100 = nothing decayed; empty brain = 100). */\n score: number;\n}\n\n/** Options for {@link brainHealth}. */\nexport interface HealthOptions {\n /** Age in days past which an active memory note is stale (default {@link DEFAULT_STALE_AFTER_DAYS}). */\n staleAfterDays?: number;\n /** \"Today\" as `YYYY-MM-DD`; defaults to the real date. Injectable for deterministic tests. */\n now?: string;\n}\n\n/** Whole days between two `YYYY-MM-DD` dates (`now - then`); negative dates/parse errors → 0. */\nfunction daysBetween(now: string, then: string): number {\n const a = Date.parse(`${now}T00:00:00Z`);\n const b = Date.parse(`${then}T00:00:00Z`);\n if (Number.isNaN(a) || Number.isNaN(b)) return 0;\n return Math.max(0, Math.floor((a - b) / 86_400_000));\n}\n\n/** Case-insensitive check for a `contradicted` tag. */\nfunction isContradicted(note: Note): boolean {\n return note.frontmatter.tags.some((t) => t.toLowerCase() === \"contradicted\");\n}\n\n/**\n * Compute the {@link HealthReport} for `notes`. Definitions:\n * - **stale**: `status: stale` (memory), OR an `active` memory note whose last touch\n * (`verified` ?? `updated` ?? `created`) is older than `staleAfterDays`.\n * - **unverified**: `active` memory notes with no `verified` date.\n * - **contradicted**: any note carrying a `contradicted` tag.\n * - **orphaned**: notes whose id is referenced by NO other note (no inbound links).\n * - **score**: `100 * (1 - (serious + 0.5·soft)/total)`, where serious = stale ∪ contradicted and\n * soft = (unverified ∪ orphaned) minus serious. Clamped to [0,100]; empty brain scores 100.\n */\nexport function brainHealth(notes: Note[], opts: HealthOptions = {}): HealthReport {\n const staleAfterDays = opts.staleAfterDays ?? DEFAULT_STALE_AFTER_DAYS;\n const now = opts.now ?? today();\n\n // Inbound-link set: every id referenced by some note (so a note IS linked to).\n const referenced = new Set<string>();\n for (const n of notes) {\n const fm = n.frontmatter;\n const refs = [\n ...fm.relates,\n ...(fm.kind === \"memory\" ? fm.sources : []),\n ...(fm.kind === \"decision\" ? fm.supersedes : []),\n ...(fm.kind === \"memory\" || fm.kind === \"decision\"\n ? [fm.superseded_by].filter((v): v is string => typeof v === \"string\")\n : []),\n ];\n // Links may be `[[id]]` or a bare id — normalize the wikilink form.\n for (const r of refs) referenced.add(r.replace(/^\\[\\[|\\]\\]$/g, \"\"));\n }\n\n const stale: string[] = [];\n const unverified: string[] = [];\n const contradicted: string[] = [];\n const orphaned: string[] = [];\n\n for (const n of notes) {\n const fm = n.frontmatter;\n const id = fm.id;\n\n if (fm.kind === \"memory\") {\n if (fm.status === \"stale\") {\n stale.push(id);\n } else if (fm.status === \"active\") {\n const lastTouch = fm.verified ?? fm.updated ?? fm.created;\n if (daysBetween(now, lastTouch) > staleAfterDays) stale.push(id);\n if (!fm.verified) unverified.push(id);\n }\n }\n\n if (isContradicted(n)) contradicted.push(id);\n if (!referenced.has(id)) orphaned.push(id);\n }\n\n const serious = new Set<string>([...stale, ...contradicted]);\n const soft = new Set<string>([...unverified, ...orphaned].filter((id) => !serious.has(id)));\n\n const total = notes.length;\n const score =\n total === 0\n ? 100\n : Math.max(\n 0,\n Math.min(100, Math.round(100 * (1 - (serious.size + 0.5 * soft.size) / total))),\n );\n\n const bucket = (ids: string[]): HealthBucket => ({ count: ids.length, ids: ids.sort() });\n return {\n total,\n stale: bucket(stale),\n unverified: bucket(unverified),\n contradicted: bucket(contradicted),\n orphaned: bucket(orphaned),\n score,\n };\n}\n\n/** Load a brain's notes and compute its {@link HealthReport}. Read-only; never writes canon. */\nexport async function computeBrainHealth(\n brainDir: string,\n opts: HealthOptions = {},\n): Promise<HealthReport> {\n return brainHealth(await listNotes(brainDir), opts);\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\n\n/**\n * A cross-PROCESS advisory lock for a brain's git operations (#100). The `SerialQueue`\n * serializes syncs WITHIN one process, but a one-shot `commonwealth sync` (or a second daemon)\n * runs in a DIFFERENT process with its own queue — nothing stopped them from interleaving\n * `git commit`/`rebase`/`push` on the same repo, racing git's own `index.lock` and corrupting an\n * in-progress rebase. This lock closes that gap: at most one process runs a sync pass at a time.\n *\n * The lock is a file at `.commonwealth/sync.lock` holding the owner pid, acquired via an atomic\n * exclusive create (`wx`). A lock whose owner process is dead is stale and reclaimed, so a crash\n * never wedges syncing forever.\n */\nconst LOCK_REL = path.join(\".commonwealth\", \"sync.lock\");\n\nfunction lockPath(brainDir: string): string {\n return path.join(brainDir, LOCK_REL);\n}\n\n/** True if `pid` names a live process (signal 0 is an existence check, sends nothing). */\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false; // ESRCH (no such process) or EPERM — treat as gone\n }\n}\n\n/** Read the owner pid recorded in the lock file, or null if missing/garbage. */\nasync function readOwner(file: string): Promise<number | null> {\n try {\n const pid = Number.parseInt((await fs.readFile(file, \"utf8\")).trim(), 10);\n return Number.isFinite(pid) ? pid : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Try to acquire the sync lock for `brainDir`. Returns a `release` function on success, or\n * `null` when another LIVE process currently holds it (the caller should skip this pass). A\n * stale lock (dead owner, or unreadable) is reclaimed and acquisition retried once. Never throws\n * for the contended case; genuine IO errors propagate.\n */\nexport async function acquireSyncLock(brainDir: string): Promise<(() => Promise<void>) | null> {\n const file = lockPath(brainDir);\n await fs.mkdir(path.dirname(file), { recursive: true });\n\n for (let attempt = 0; attempt < 2; attempt++) {\n try {\n const fh = await fs.open(file, \"wx\"); // atomic: fails if the lock already exists\n try {\n await fh.write(`${process.pid}\\n`);\n } finally {\n await fh.close();\n }\n return async () => {\n await fs.rm(file, { force: true });\n };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"EEXIST\") throw err;\n const owner = await readOwner(file);\n if (owner !== null && isAlive(owner)) return null; // held by a live process\n // Stale (dead owner) or unreadable → reclaim and retry once.\n await fs.rm(file, { force: true });\n }\n }\n return null;\n}\n"],"mappings":"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","names":["fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","execFile","existsSync","path","promisify","pexec","fs","path"]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@cmnwlth/core",
3
+ "version": "0.1.0",
4
+ "description": "Core substrate for Commonwealth: schema, note IO, scaffold, and the derived index",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "dependencies": {
19
+ "better-sqlite3": "^11.0.0",
20
+ "github-slugger": "^2.0.0",
21
+ "gray-matter": "^4.0.3",
22
+ "nanoid": "^5.0.0",
23
+ "zod": "^3.23.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/better-sqlite3": "^7.6.0"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public",
30
+ "provenance": true
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/kristoffeys/commonwealth.git",
35
+ "directory": "packages/core"
36
+ },
37
+ "homepage": "https://github.com/kristoffeys/commonwealth#readme",
38
+ "bugs": "https://github.com/kristoffeys/commonwealth/issues",
39
+ "scripts": {
40
+ "build": "tsup",
41
+ "typecheck": "tsc --noEmit"
42
+ }
43
+ }