@theglitchking/semantic-memory 1.5.2 → 1.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +22 -0
  4. package/README.md +4 -0
  5. package/dist/{chunk-2EELGTLX.js → chunk-D5QLNNA4.js} +2 -2
  6. package/dist/{chunk-A3KYHKB5.js → chunk-FTRXH2WC.js} +8 -4
  7. package/dist/chunk-FTRXH2WC.js.map +1 -0
  8. package/dist/{chunk-OWZWMB4P.js → chunk-FURCIJBO.js} +1 -1
  9. package/dist/chunk-FURCIJBO.js.map +1 -0
  10. package/dist/{chunk-S4KW7VH4.js → chunk-LGQPP5FQ.js} +8 -3
  11. package/dist/chunk-LGQPP5FQ.js.map +1 -0
  12. package/dist/{chunk-NTYYS53O.js → chunk-NBY4TRP7.js} +7 -3
  13. package/dist/chunk-NBY4TRP7.js.map +1 -0
  14. package/dist/chunk-OEF5U5GV.js +175 -0
  15. package/dist/chunk-OEF5U5GV.js.map +1 -0
  16. package/dist/{chunk-FM26NFTR.js → chunk-OFXQXVG5.js} +26 -12
  17. package/dist/chunk-OFXQXVG5.js.map +1 -0
  18. package/dist/{chunk-JWPR2B2X.js → chunk-ROKSUJFM.js} +22 -11
  19. package/dist/chunk-ROKSUJFM.js.map +1 -0
  20. package/dist/{chunk-JPQHNG3R.js → chunk-SX427M2R.js} +10 -4
  21. package/dist/chunk-SX427M2R.js.map +1 -0
  22. package/dist/{chunk-7M3JZOYH.js → chunk-WZEKIUYG.js} +8 -4
  23. package/dist/chunk-WZEKIUYG.js.map +1 -0
  24. package/dist/{chunk-WSU4QIPB.js → chunk-XAXK7NM4.js} +14 -8
  25. package/dist/chunk-XAXK7NM4.js.map +1 -0
  26. package/dist/cli/index.js +13 -13
  27. package/dist/core/index.d.ts +24 -4
  28. package/dist/core/index.js +18 -10
  29. package/dist/core/redact.d.ts +36 -0
  30. package/dist/core/redact.js +18 -0
  31. package/dist/{dossier-2UG724LB.js → dossier-RWTIMGZN.js} +4 -3
  32. package/dist/healthcheck-A32IWPNV.js +20 -0
  33. package/dist/{lexicon-5PXQEMUF.js → lexicon-IVNJTMWE.js} +5 -4
  34. package/dist/lint-HURYGO3V.js +17 -0
  35. package/dist/log-YIXF6CYM.js +11 -0
  36. package/dist/mcp/server.js +29 -24
  37. package/dist/mcp/server.js.map +1 -1
  38. package/dist/{profile-LXUEF7TX.js → profile-UE4YVTDC.js} +5 -4
  39. package/dist/{schema-ATFCLC6Y.js → schema-LY6533NJ.js} +2 -2
  40. package/dist/{telemetry-GB2TEHVE.js → telemetry-B4KP3UVE.js} +4 -3
  41. package/dist/telemetry-B4KP3UVE.js.map +1 -0
  42. package/hooks/vault-context.js +17 -3
  43. package/package.json +1 -1
  44. package/dist/chunk-7M3JZOYH.js.map +0 -1
  45. package/dist/chunk-A3KYHKB5.js.map +0 -1
  46. package/dist/chunk-FM26NFTR.js.map +0 -1
  47. package/dist/chunk-JPQHNG3R.js.map +0 -1
  48. package/dist/chunk-JWPR2B2X.js.map +0 -1
  49. package/dist/chunk-NTYYS53O.js.map +0 -1
  50. package/dist/chunk-OWZWMB4P.js.map +0 -1
  51. package/dist/chunk-S4KW7VH4.js.map +0 -1
  52. package/dist/chunk-WSU4QIPB.js.map +0 -1
  53. package/dist/healthcheck-IMB47LZE.js +0 -19
  54. package/dist/lint-XUQ7JDYX.js +0 -16
  55. package/dist/log-LQXIJXIA.js +0 -10
  56. /package/dist/{chunk-2EELGTLX.js.map → chunk-D5QLNNA4.js.map} +0 -0
  57. /package/dist/{dossier-2UG724LB.js.map → core/redact.js.map} +0 -0
  58. /package/dist/{healthcheck-IMB47LZE.js.map → dossier-RWTIMGZN.js.map} +0 -0
  59. /package/dist/{lexicon-5PXQEMUF.js.map → healthcheck-A32IWPNV.js.map} +0 -0
  60. /package/dist/{lint-XUQ7JDYX.js.map → lexicon-IVNJTMWE.js.map} +0 -0
  61. /package/dist/{log-LQXIJXIA.js.map → lint-HURYGO3V.js.map} +0 -0
  62. /package/dist/{profile-LXUEF7TX.js.map → log-YIXF6CYM.js.map} +0 -0
  63. /package/dist/{schema-ATFCLC6Y.js.map → profile-UE4YVTDC.js.map} +0 -0
  64. /package/dist/{telemetry-GB2TEHVE.js.map → schema-LY6533NJ.js.map} +0 -0
package/dist/cli/index.js CHANGED
@@ -637,7 +637,7 @@ program.command("search <query>").description("Run a vault search and print top
637
637
  }
638
638
  });
639
639
  program.command("lint").description("Lint the vault against vault.schema.yml (schema violations + missing provenance + stale)").requiredOption("--notes <path>", "Path to markdown notes directory").option("--rule <name>", "Limit output to one rule: schema_violations | missing_provenance | stale").option("--json", "Emit JSON instead of the human-readable report").option("--strict", "Exit non-zero on warnings too (default: exit non-zero only on errors)").action(async (opts) => {
640
- const { lintVault, formatLintReport } = await import("../lint-XUQ7JDYX.js");
640
+ const { lintVault, formatLintReport } = await import("../lint-HURYGO3V.js");
641
641
  const report = await lintVault(resolve2(opts.notes));
642
642
  if (opts.json) {
643
643
  const out = opts.rule ? report.byRule[opts.rule] : report;
@@ -649,7 +649,7 @@ program.command("lint").description("Lint the vault against vault.schema.yml (sc
649
649
  process.exitCode = bad > 0 ? 1 : 0;
650
650
  });
651
651
  program.command("log-event").description("Append a structured event to the vault's log.md (used by hooks and CI scripts \u2014 same shape as mcp__semantic-vault__log_event)").requiredOption("--notes <path>", "Path to markdown notes directory").requiredOption("--kind <name>", "Event category: ingest, synthesis, error, mode_change, etc.").requiredOption("--summary <text>", "One-line human summary").option("--payload <json>", "Structured payload as JSON string").action(async (opts) => {
652
- const { logEvent } = await import("../log-LQXIJXIA.js");
652
+ const { logEvent } = await import("../log-YIXF6CYM.js");
653
653
  let payload;
654
654
  if (opts.payload) {
655
655
  try {
@@ -673,7 +673,7 @@ program.command("log-event").description("Append a structured event to the vault
673
673
  }
674
674
  });
675
675
  program.command("log-query").description("Read structured log entries from log.md \u2014 filters by kind, date range, limit").requiredOption("--notes <path>", "Path to markdown notes directory").option("--kind <name>", "Filter by kind (ingest, synthesis, error, mode_change, etc.)").option("--after <iso>", "ISO timestamp \u2014 only entries on or after").option("--before <iso>", "ISO timestamp \u2014 only entries on or before").option("--limit <n>", "Max entries (most recent)", (v) => parseInt(v, 10)).action(async (opts) => {
676
- const { logQuery } = await import("../log-LQXIJXIA.js");
676
+ const { logQuery } = await import("../log-YIXF6CYM.js");
677
677
  try {
678
678
  const entries = await logQuery(resolve2(opts.notes), {
679
679
  kind: opts.kind,
@@ -688,7 +688,7 @@ program.command("log-query").description("Read structured log entries from log.m
688
688
  }
689
689
  });
690
690
  program.command("install-schema").description("Bootstrap vault.schema.yml in the vault root with the default schema").requiredOption("--notes <path>", "Path to markdown notes directory").option("--force", "Overwrite existing schema file").action(async (opts) => {
691
- const { installDefaultSchema } = await import("../schema-ATFCLC6Y.js");
691
+ const { installDefaultSchema } = await import("../schema-LY6533NJ.js");
692
692
  const r = await installDefaultSchema(resolve2(opts.notes), opts.force);
693
693
  console.log(r.written ? `Installed default schema: ${r.path}` : `Schema already exists: ${r.path} (use --force to overwrite)`);
694
694
  process.exit(0);
@@ -869,7 +869,7 @@ ${r2.stderr?.toString() || ""}`);
869
869
  }
870
870
  }
871
871
  if (smokeOk && !opts.json) console.log(`\u2713 local install starts cleanly (v${smokeVersion})`);
872
- const { runHealthcheck, formatDriftBanner, filterToDrift } = await import("../healthcheck-IMB47LZE.js");
872
+ const { runHealthcheck, formatDriftBanner, filterToDrift } = await import("../healthcheck-A32IWPNV.js");
873
873
  const vaultCandidate = join3(cwd, ".claude", ".vault");
874
874
  const vaultPath = existsSync3(vaultCandidate) ? vaultCandidate : void 0;
875
875
  let result = await runHealthcheck({ projectRoot: cwd, vaultPath, tier: opts.fast ? "fast" : "all", force: true });
@@ -1038,49 +1038,49 @@ program.command("decay-trace <notePath>").description("Show the decay calculatio
1038
1038
  });
1039
1039
  var lexiconCmd = program.command("lexicon").description("Manage the learned human\u2192artifact lexicon (aliases).");
1040
1040
  lexiconCmd.command("list").description("List all aliases in the lexicon.").requiredOption("--notes <path>", "Path to markdown notes directory").action(async (opts) => {
1041
- const { loadLexiconCache } = await import("../lexicon-5PXQEMUF.js");
1041
+ const { loadLexiconCache } = await import("../lexicon-IVNJTMWE.js");
1042
1042
  console.log(JSON.stringify(await loadLexiconCache(resolve2(opts.notes)), null, 2));
1043
1043
  process.exit(0);
1044
1044
  });
1045
1045
  lexiconCmd.command("compile").description("Rebuild the derived lexicon cache from the lexicon/ notes.").requiredOption("--notes <path>", "Path to markdown notes directory").action(async (opts) => {
1046
- const { compileLexicon } = await import("../lexicon-5PXQEMUF.js");
1046
+ const { compileLexicon } = await import("../lexicon-IVNJTMWE.js");
1047
1047
  const entries = await compileLexicon(resolve2(opts.notes));
1048
1048
  console.log(`compiled ${entries.length} alias(es)`);
1049
1049
  process.exit(0);
1050
1050
  });
1051
1051
  lexiconCmd.command("add <canonical> <phrases...>").description("Upsert an alias: a canonical target and the human phrases that refer to it.").requiredOption("--notes <path>", "Path to markdown notes directory").option("--authored", "Mark as human-authored (default: learned)").action(async (canonical, phrases, opts) => {
1052
- const { addAlias } = await import("../lexicon-5PXQEMUF.js");
1052
+ const { addAlias } = await import("../lexicon-IVNJTMWE.js");
1053
1053
  const r = await addAlias(resolve2(opts.notes), { canonical, phrases, source: opts.authored ? "authored" : "learned" });
1054
1054
  console.log(JSON.stringify(r, null, 2));
1055
1055
  process.exit(0);
1056
1056
  });
1057
1057
  var dossierCmd = program.command("dossier").description("Manage entity dossiers \u2014 per-component living notes (purpose / failure modes / knobs / incident log / current state).");
1058
1058
  dossierCmd.command("init <entity>").description("Scaffold a dossier for an entity (no-op if one already exists). Optionally seed aliases and provenance.").requiredOption("--notes <path>", "Path to markdown notes directory").option("--alias <phrase...>", "Human phrase(s) for this entity \u2014 fed to the lexicon compiler").option("--seeded-from <ref>", "Provenance of the scaffold (e.g. a babel-fish project-map entry)").action(async (entity, opts) => {
1059
- const { initDossier } = await import("../dossier-2UG724LB.js");
1059
+ const { initDossier } = await import("../dossier-RWTIMGZN.js");
1060
1060
  const r = await initDossier(resolve2(opts.notes), entity, { aliases: opts.alias, seeded_from: opts.seededFrom });
1061
1061
  console.log(JSON.stringify(r, null, 2));
1062
1062
  process.exit(0);
1063
1063
  });
1064
1064
  dossierCmd.command("list").description("List all dossiers with their entity, aliases, and current state.").requiredOption("--notes <path>", "Path to markdown notes directory").action(async (opts) => {
1065
- const { listDossiers } = await import("../dossier-2UG724LB.js");
1065
+ const { listDossiers } = await import("../dossier-RWTIMGZN.js");
1066
1066
  console.log(JSON.stringify(await listDossiers(resolve2(opts.notes)), null, 2));
1067
1067
  process.exit(0);
1068
1068
  });
1069
1069
  var profileCmd = program.command("profile").description("Manage the speaker profile \u2014 how THIS human communicates (severity calibration, chronic omissions, verbosity, shorthand).");
1070
1070
  profileCmd.command("init").description("Scaffold profile/speaker.md with the fixed sections (no-op if it exists).").requiredOption("--notes <path>", "Path to markdown notes directory").action(async (opts) => {
1071
- const { initSpeakerProfile } = await import("../profile-LXUEF7TX.js");
1071
+ const { initSpeakerProfile } = await import("../profile-UE4YVTDC.js");
1072
1072
  const r = await initSpeakerProfile(resolve2(opts.notes));
1073
1073
  console.log(JSON.stringify(r, null, 2));
1074
1074
  process.exit(0);
1075
1075
  });
1076
1076
  profileCmd.command("show").description("Print the speaker profile's injection head (the capped, placeholder-stripped view).").requiredOption("--notes <path>", "Path to markdown notes directory").action(async (opts) => {
1077
- const { readSpeakerProfile } = await import("../profile-LXUEF7TX.js");
1077
+ const { readSpeakerProfile } = await import("../profile-UE4YVTDC.js");
1078
1078
  const p = await readSpeakerProfile(resolve2(opts.notes));
1079
1079
  console.log(p ? p.head || "(profile is empty \u2014 only placeholders)" : "(no speaker profile \u2014 run `profile init`)");
1080
1080
  process.exit(0);
1081
1081
  });
1082
1082
  program.command("selection-stats").description("Summarize the local selection log: searches, selections, most-cited notes, and retrieved-but-never-cited notes.").requiredOption("--notes <path>", "Path to markdown notes directory").option("--json", "Emit raw JSON instead of a human summary").action(async (opts) => {
1083
- const { computeSelectionStats, selectionLogPath } = await import("../telemetry-GB2TEHVE.js");
1083
+ const { computeSelectionStats, selectionLogPath } = await import("../telemetry-B4KP3UVE.js");
1084
1084
  const stats = await computeSelectionStats(resolve2(opts.notes));
1085
1085
  if (opts.json) {
1086
1086
  console.log(JSON.stringify(stats, null, 2));
@@ -1,5 +1,6 @@
1
1
  import Graph from 'graphology';
2
2
  import { EventEmitter } from 'node:events';
3
+ export { REDACTED, RedactMode, RedactResult, redact, redactDeep } from './redact.js';
3
4
 
4
5
  interface IndexedDocument {
5
6
  path: string;
@@ -182,13 +183,18 @@ declare class TextSearch {
182
183
  search(options: SearchTextOptions): SearchResult[];
183
184
  }
184
185
 
186
+ /** `redacted`: secrets masked in the content written (never the values). */
187
+ interface NoteWriteResult {
188
+ path: string;
189
+ redacted: number;
190
+ }
185
191
  declare class NoteCrud {
186
192
  private notesPath;
187
193
  constructor(notesPath: string);
188
- create(relativePath: string, content: string, frontmatter?: Record<string, unknown>): Promise<string>;
194
+ create(relativePath: string, content: string, frontmatter?: Record<string, unknown>): Promise<NoteWriteResult>;
189
195
  read(relativePath: string): Promise<string>;
190
196
  readMultiple(paths: string[]): Promise<Map<string, string>>;
191
- update(relativePath: string, content: string, options: UpdateNoteOptions): Promise<void>;
197
+ update(relativePath: string, content: string, options: UpdateNoteOptions): Promise<NoteWriteResult>;
192
198
  delete(relativePath: string): Promise<void>;
193
199
  move(fromPath: string, toPath: string): Promise<void>;
194
200
  private updateWikilinksAfterMove;
@@ -199,7 +205,9 @@ declare class FrontmatterManager {
199
205
  private notesPath;
200
206
  constructor(notesPath: string);
201
207
  get(relativePath: string): Promise<Record<string, unknown>>;
202
- update(relativePath: string, fields: Record<string, unknown>): Promise<void>;
208
+ update(relativePath: string, fields: Record<string, unknown>): Promise<{
209
+ redacted: number;
210
+ }>;
203
211
  }
204
212
  declare class TagManager {
205
213
  private notesPath;
@@ -252,7 +260,7 @@ interface VaultSchema {
252
260
  type Severity$1 = "warn" | "error";
253
261
  interface LintFinding {
254
262
  path: string;
255
- rule: "missing_provenance" | "stale" | "schema_violations" | "broken_links" | "code_symbols" | "decay_candidates" | "alias_conflicts" | "decoys";
263
+ rule: "missing_provenance" | "stale" | "schema_violations" | "broken_links" | "code_symbols" | "decay_candidates" | "alias_conflicts" | "decoys" | "secrets";
256
264
  severity: Severity$1;
257
265
  message: string;
258
266
  }
@@ -337,6 +345,8 @@ interface ApplyPatchOptions {
337
345
  interface AppliedOp {
338
346
  op: "create" | "update" | "delete" | "move";
339
347
  path: string;
348
+ /** secrets masked in this op's content; omitted when none */
349
+ redacted?: number;
340
350
  }
341
351
  interface ApplyPatchResult {
342
352
  ok: boolean;
@@ -530,6 +540,8 @@ interface LintReport {
530
540
  decay_candidates: LintFinding[];
531
541
  alias_conflicts: LintFinding[];
532
542
  decoys: LintFinding[];
543
+ /** only present when the opt-in secrets check ran */
544
+ secrets?: LintFinding[];
533
545
  };
534
546
  counts: {
535
547
  errors: number;
@@ -572,6 +584,14 @@ declare function lintVault(notesPath: string, opts?: {
572
584
  * signal (decision Q5). Opt-in; a no-op with no selection log.
573
585
  */
574
586
  checkDecoys?: boolean;
587
+ /**
588
+ * When true, run the secrets check (v1.5.3): flag notes that contain a secret
589
+ * (API key, token, password, private key — the redactor's precise set). Reports
590
+ * path, line and kind, never the value; nothing is rewritten. Opt-in, so the
591
+ * default report stays byte-stable. A real secret must be rotated: it is in
592
+ * git history if the note was ever committed.
593
+ */
594
+ checkSecrets?: boolean;
575
595
  }): Promise<LintReport>;
576
596
  declare function formatLintReport(report: LintReport, opts?: {
577
597
  rule?: keyof LintReport["byRule"];
@@ -2,7 +2,7 @@ import {
2
2
  filterToDrift,
3
3
  formatDriftBanner,
4
4
  runHealthcheck
5
- } from "../chunk-2EELGTLX.js";
5
+ } from "../chunk-D5QLNNA4.js";
6
6
  import {
7
7
  FrontmatterManager,
8
8
  INDEX_FILE,
@@ -18,19 +18,20 @@ import {
18
18
  regenDirectoryIndex,
19
19
  regenIndexesForPaths,
20
20
  regenerateAgentsContract
21
- } from "../chunk-JWPR2B2X.js";
21
+ } from "../chunk-ROKSUJFM.js";
22
22
  import {
23
23
  formatLintReport,
24
24
  lintVault
25
- } from "../chunk-FM26NFTR.js";
26
- import "../chunk-NTYYS53O.js";
27
- import "../chunk-A3KYHKB5.js";
28
- import "../chunk-WSU4QIPB.js";
25
+ } from "../chunk-OFXQXVG5.js";
26
+ import "../chunk-5ZKNO6ZD.js";
27
+ import "../chunk-NBY4TRP7.js";
28
+ import "../chunk-FTRXH2WC.js";
29
+ import "../chunk-XAXK7NM4.js";
29
30
  import {
30
31
  SessionManager,
31
32
  deriveProjectRoot,
32
33
  deriveSessionDir
33
- } from "../chunk-S4KW7VH4.js";
34
+ } from "../chunk-LGQPP5FQ.js";
34
35
  import {
35
36
  Embedder,
36
37
  GraphBuilder,
@@ -43,13 +44,17 @@ import {
43
44
  import {
44
45
  logEvent,
45
46
  logQuery
46
- } from "../chunk-JPQHNG3R.js";
47
+ } from "../chunk-SX427M2R.js";
48
+ import {
49
+ REDACTED,
50
+ redact,
51
+ redactDeep
52
+ } from "../chunk-OEF5U5GV.js";
47
53
  import {
48
54
  installDefaultSchema,
49
55
  loadSchema,
50
56
  validateNote
51
- } from "../chunk-OWZWMB4P.js";
52
- import "../chunk-5ZKNO6ZD.js";
57
+ } from "../chunk-FURCIJBO.js";
53
58
  import "../chunk-PZ5AY32C.js";
54
59
  export {
55
60
  Embedder,
@@ -59,6 +64,7 @@ export {
59
64
  INDEX_OVERFLOW_THRESHOLD,
60
65
  Indexer,
61
66
  NoteCrud,
67
+ REDACTED,
62
68
  SessionManager,
63
69
  TagManager,
64
70
  TextSearch,
@@ -79,6 +85,8 @@ export {
79
85
  loadSchema,
80
86
  logEvent,
81
87
  logQuery,
88
+ redact,
89
+ redactDeep,
82
90
  regenDirectoryIndex,
83
91
  regenIndexesForPaths,
84
92
  regenerateAgentsContract,
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Secret redaction for everything semantic-memory writes to disk. Ported from jev-loop's
3
+ * redact.py: (1) exact values of secret-named env vars on this machine, (2) patterns.
4
+ *
5
+ * Two pattern sets:
6
+ * - "precise" (notes, frontmatter, dossiers, profile, lexicon): only shapes that are almost
7
+ * never ordinary content, because a false positive in a note is data loss.
8
+ * - "broad" (search log, log.md events, session state, capture-pending): precise plus long
9
+ * base64 / letter-and-digit tokens; over-redaction is fine in logs.
10
+ *
11
+ * Cannot catch a secret written in plain prose ("the password is hunter2"). Never logs values.
12
+ */
13
+ declare const REDACTED = "[REDACTED]";
14
+ type RedactMode = "precise" | "broad";
15
+ interface RedactResult {
16
+ text: string;
17
+ count: number;
18
+ }
19
+ /** Test seam: re-read env and settings on the next call. */
20
+ declare function resetRedactCache(): void;
21
+ declare function redact(text: string, mode?: RedactMode): RedactResult;
22
+ interface SecretLocation {
23
+ line: number;
24
+ kind: string;
25
+ }
26
+ /** Where precise-set secrets sit in a text (for lint_vault): 1-based line and kind, never the value. */
27
+ declare function findSecrets(text: string): SecretLocation[];
28
+ /** Redact every string inside a JSON-like value (for log payloads and state files). */
29
+ declare function redactDeep<T>(value: T, mode?: RedactMode): {
30
+ value: T;
31
+ count: number;
32
+ };
33
+ /** Suffix for a tool result: says how many secrets were masked, never which. "" when none. */
34
+ declare function redactedNote(count: number): string;
35
+
36
+ export { REDACTED, type RedactMode, type RedactResult, type SecretLocation, findSecrets, redact, redactDeep, redactedNote, resetRedactCache };
@@ -0,0 +1,18 @@
1
+ import {
2
+ REDACTED,
3
+ findSecrets,
4
+ redact,
5
+ redactDeep,
6
+ redactedNote,
7
+ resetRedactCache
8
+ } from "../chunk-OEF5U5GV.js";
9
+ import "../chunk-PZ5AY32C.js";
10
+ export {
11
+ REDACTED,
12
+ findSecrets,
13
+ redact,
14
+ redactDeep,
15
+ redactedNote,
16
+ resetRedactCache
17
+ };
18
+ //# sourceMappingURL=redact.js.map
@@ -15,8 +15,9 @@ import {
15
15
  resolveDossierPath,
16
16
  setCurrentState,
17
17
  slugifyEntity
18
- } from "./chunk-WSU4QIPB.js";
19
- import "./chunk-S4KW7VH4.js";
18
+ } from "./chunk-XAXK7NM4.js";
19
+ import "./chunk-LGQPP5FQ.js";
20
+ import "./chunk-OEF5U5GV.js";
20
21
  import "./chunk-PZ5AY32C.js";
21
22
  export {
22
23
  DOSSIER_DIR,
@@ -36,4 +37,4 @@ export {
36
37
  setCurrentState,
37
38
  slugifyEntity
38
39
  };
39
- //# sourceMappingURL=dossier-2UG724LB.js.map
40
+ //# sourceMappingURL=dossier-RWTIMGZN.js.map
@@ -0,0 +1,20 @@
1
+ import {
2
+ filterToDrift,
3
+ formatDriftBanner,
4
+ runHealthcheck
5
+ } from "./chunk-D5QLNNA4.js";
6
+ import "./chunk-OFXQXVG5.js";
7
+ import "./chunk-5ZKNO6ZD.js";
8
+ import "./chunk-NBY4TRP7.js";
9
+ import "./chunk-FTRXH2WC.js";
10
+ import "./chunk-XAXK7NM4.js";
11
+ import "./chunk-LGQPP5FQ.js";
12
+ import "./chunk-OEF5U5GV.js";
13
+ import "./chunk-FURCIJBO.js";
14
+ import "./chunk-PZ5AY32C.js";
15
+ export {
16
+ filterToDrift,
17
+ formatDriftBanner,
18
+ runHealthcheck
19
+ };
20
+ //# sourceMappingURL=healthcheck-A32IWPNV.js.map
@@ -8,9 +8,10 @@ import {
8
8
  normalizePhrase,
9
9
  removeAlias,
10
10
  slugify
11
- } from "./chunk-A3KYHKB5.js";
12
- import "./chunk-WSU4QIPB.js";
13
- import "./chunk-S4KW7VH4.js";
11
+ } from "./chunk-FTRXH2WC.js";
12
+ import "./chunk-XAXK7NM4.js";
13
+ import "./chunk-LGQPP5FQ.js";
14
+ import "./chunk-OEF5U5GV.js";
14
15
  import "./chunk-PZ5AY32C.js";
15
16
  export {
16
17
  addAlias,
@@ -23,4 +24,4 @@ export {
23
24
  removeAlias,
24
25
  slugify
25
26
  };
26
- //# sourceMappingURL=lexicon-5PXQEMUF.js.map
27
+ //# sourceMappingURL=lexicon-IVNJTMWE.js.map
@@ -0,0 +1,17 @@
1
+ import {
2
+ formatLintReport,
3
+ lintVault
4
+ } from "./chunk-OFXQXVG5.js";
5
+ import "./chunk-5ZKNO6ZD.js";
6
+ import "./chunk-NBY4TRP7.js";
7
+ import "./chunk-FTRXH2WC.js";
8
+ import "./chunk-XAXK7NM4.js";
9
+ import "./chunk-LGQPP5FQ.js";
10
+ import "./chunk-OEF5U5GV.js";
11
+ import "./chunk-FURCIJBO.js";
12
+ import "./chunk-PZ5AY32C.js";
13
+ export {
14
+ formatLintReport,
15
+ lintVault
16
+ };
17
+ //# sourceMappingURL=lint-HURYGO3V.js.map
@@ -0,0 +1,11 @@
1
+ import {
2
+ logEvent,
3
+ logQuery
4
+ } from "./chunk-SX427M2R.js";
5
+ import "./chunk-OEF5U5GV.js";
6
+ import "./chunk-PZ5AY32C.js";
7
+ export {
8
+ logEvent,
9
+ logQuery
10
+ };
11
+ //# sourceMappingURL=log-YIXF6CYM.js.map
@@ -3,7 +3,7 @@ import {
3
3
  initSpeakerProfile,
4
4
  readSpeakerProfile,
5
5
  updateProfileSection
6
- } from "../chunk-7M3JZOYH.js";
6
+ } from "../chunk-WZEKIUYG.js";
7
7
  import {
8
8
  FrontmatterManager,
9
9
  NoteCrud,
@@ -17,23 +17,28 @@ import {
17
17
  regenDirectoryIndex,
18
18
  regenIndexesForPaths,
19
19
  regenerateAgentsContract
20
- } from "../chunk-JWPR2B2X.js";
20
+ } from "../chunk-ROKSUJFM.js";
21
21
  import {
22
22
  lintVault
23
- } from "../chunk-FM26NFTR.js";
23
+ } from "../chunk-OFXQXVG5.js";
24
+ import {
25
+ computeDecay,
26
+ loadDecayConfig,
27
+ normalizeVerifiedDate
28
+ } from "../chunk-5ZKNO6ZD.js";
24
29
  import {
25
30
  appendEvent,
26
31
  readSelectionLog,
27
32
  recordSearchForCorrelation,
28
33
  wasRecentlySearched
29
- } from "../chunk-NTYYS53O.js";
34
+ } from "../chunk-NBY4TRP7.js";
30
35
  import {
31
36
  addAlias,
32
37
  compileLexicon,
33
38
  expandQuery,
34
39
  loadLexiconCache,
35
40
  removeAlias
36
- } from "../chunk-A3KYHKB5.js";
41
+ } from "../chunk-FTRXH2WC.js";
37
42
  import {
38
43
  appendIncident,
39
44
  compileDossiers,
@@ -42,12 +47,12 @@ import {
42
47
  listDossiers,
43
48
  resolveDossierPath,
44
49
  setCurrentState
45
- } from "../chunk-WSU4QIPB.js";
50
+ } from "../chunk-XAXK7NM4.js";
46
51
  import {
47
52
  SessionManager,
48
53
  deriveProjectRoot,
49
54
  deriveSessionDir
50
- } from "../chunk-S4KW7VH4.js";
55
+ } from "../chunk-LGQPP5FQ.js";
51
56
  import {
52
57
  Embedder,
53
58
  GraphBuilder,
@@ -60,15 +65,13 @@ import {
60
65
  import {
61
66
  logEvent,
62
67
  logQuery
63
- } from "../chunk-JPQHNG3R.js";
68
+ } from "../chunk-SX427M2R.js";
64
69
  import {
65
- installDefaultSchema
66
- } from "../chunk-OWZWMB4P.js";
70
+ redactedNote
71
+ } from "../chunk-OEF5U5GV.js";
67
72
  import {
68
- computeDecay,
69
- loadDecayConfig,
70
- normalizeVerifiedDate
71
- } from "../chunk-5ZKNO6ZD.js";
73
+ installDefaultSchema
74
+ } from "../chunk-FURCIJBO.js";
72
75
  import {
73
76
  __export
74
77
  } from "../chunk-PZ5AY32C.js";
@@ -4692,8 +4695,8 @@ function registerWriteTools(server, ctx) {
4692
4695
  frontmatter: external_exports.record(external_exports.unknown()).optional()
4693
4696
  },
4694
4697
  async ({ path, content, frontmatter }) => {
4695
- await ctx.crud.create(path, content, frontmatter);
4696
- return ctx.textResponse(`Created: ${path}`);
4698
+ const { redacted } = await ctx.crud.create(path, content, frontmatter);
4699
+ return ctx.textResponse(`Created: ${path}${redactedNote(redacted)}`);
4697
4700
  }
4698
4701
  );
4699
4702
  server.tool(
@@ -4706,8 +4709,8 @@ function registerWriteTools(server, ctx) {
4706
4709
  heading: external_exports.string().optional()
4707
4710
  },
4708
4711
  async ({ path, content, mode, heading }) => {
4709
- await ctx.crud.update(path, content, { mode, heading });
4710
- return ctx.textResponse(`Updated: ${path} (${mode})`);
4712
+ const { redacted } = await ctx.crud.update(path, content, { mode, heading });
4713
+ return ctx.textResponse(`Updated: ${path} (${mode})${redactedNote(redacted)}`);
4711
4714
  }
4712
4715
  );
4713
4716
  server.tool(
@@ -5198,7 +5201,8 @@ var RULE_KEY_FOR_CHECK = {
5198
5201
  code_symbols: "code_symbols",
5199
5202
  decay_candidates: "decay_candidates",
5200
5203
  alias_conflicts: "alias_conflicts",
5201
- decoys: "decoys"
5204
+ decoys: "decoys",
5205
+ secrets: "secrets"
5202
5206
  };
5203
5207
  function registerLintTools(server, ctx) {
5204
5208
  server.tool(
@@ -5239,10 +5243,10 @@ function registerLintTools(server, ctx) {
5239
5243
  );
5240
5244
  server.tool(
5241
5245
  "lint_vault",
5242
- "Run lint rules across the vault. Default returns the full LintReport with all findings grouped by rule. Pass `checks` to filter to specific rules (schema, provenance, stale, broken_links, code_symbols, decay_candidates) \u2014 when filtered, byRule contains only the requested rules. Two checks are opt-in only (never in the default report): `code_symbols` flags inline-code file-path references that no longer exist under the project root (no-op outside a code repo); `decay_candidates` cross-references the selection log against current decay to surface frequently-retrieved-but-decayed notes (no-op with no selection log). `decoys` flags notes retrieved 3+ times but never cited - surfaced for review, never auto-down-ranked (v1.5 Q5).",
5246
+ "Run lint rules across the vault. Default returns the full LintReport with all findings grouped by rule. Pass `checks` to filter to specific rules (schema, provenance, stale, broken_links, code_symbols, decay_candidates) \u2014 when filtered, byRule contains only the requested rules. Two checks are opt-in only (never in the default report): `code_symbols` flags inline-code file-path references that no longer exist under the project root (no-op outside a code repo); `decay_candidates` cross-references the selection log against current decay to surface frequently-retrieved-but-decayed notes (no-op with no selection log). `decoys` flags notes retrieved 3+ times but never cited - surfaced for review, never auto-down-ranked (v1.5 Q5). `secrets` flags notes containing an API key, token, password or private key (path, line, kind \u2014 never the value; nothing is rewritten): rotate the secret, then remove it.",
5243
5247
  {
5244
5248
  pathGlob: external_exports.string().optional(),
5245
- checks: external_exports.array(external_exports.enum(["schema", "provenance", "stale", "broken_links", "code_symbols", "decay_candidates", "alias_conflicts", "decoys"])).optional().describe("Filter to specific lint rules. Omit for full report (excludes the opt-in code_symbols / decay_candidates / alias_conflicts / decoys).")
5249
+ checks: external_exports.array(external_exports.enum(["schema", "provenance", "stale", "broken_links", "code_symbols", "decay_candidates", "alias_conflicts", "decoys", "secrets"])).optional().describe("Filter to specific lint rules. Omit for full report (excludes the opt-in code_symbols / decay_candidates / alias_conflicts / decoys / secrets).")
5246
5250
  },
5247
5251
  async ({ pathGlob, checks }) => {
5248
5252
  const report = await lintVault(ctx.notesPath, {
@@ -5250,7 +5254,8 @@ function registerLintTools(server, ctx) {
5250
5254
  checkCodeSymbols: !!checks?.includes("code_symbols"),
5251
5255
  checkDecayCandidates: !!checks?.includes("decay_candidates"),
5252
5256
  checkAliasConflicts: !!checks?.includes("alias_conflicts"),
5253
- checkDecoys: !!checks?.includes("decoys")
5257
+ checkDecoys: !!checks?.includes("decoys"),
5258
+ checkSecrets: !!checks?.includes("secrets")
5254
5259
  });
5255
5260
  if (!checks || checks.length === 0) {
5256
5261
  return ctx.textResponse(JSON.stringify(report, null, 2));
@@ -5349,8 +5354,8 @@ function registerMetadataTools(server, ctx) {
5349
5354
  "Set or delete YAML frontmatter keys \u2014 pass null to delete a key",
5350
5355
  { path: external_exports.string(), fields: external_exports.record(external_exports.unknown()) },
5351
5356
  async ({ path, fields }) => {
5352
- await ctx.frontmatterManager.update(path, fields);
5353
- return ctx.textResponse(`Frontmatter updated: ${path}`);
5357
+ const { redacted } = await ctx.frontmatterManager.update(path, fields);
5358
+ return ctx.textResponse(`Frontmatter updated: ${path}${redactedNote(redacted)}`);
5354
5359
  }
5355
5360
  );
5356
5361
  server.tool(