@mneme-ai/mcp 1.2.0 → 1.4.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.
Files changed (36) hide show
  1. package/dist/index.d.ts.map +1 -1
  2. package/dist/index.js +39 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/tools/_capabilities.d.ts.map +1 -1
  5. package/dist/tools/_capabilities.js +29 -7
  6. package/dist/tools/_capabilities.js.map +1 -1
  7. package/dist/tools/_grader_engine.d.ts +22 -0
  8. package/dist/tools/_grader_engine.d.ts.map +1 -0
  9. package/dist/tools/_grader_engine.js +400 -0
  10. package/dist/tools/_grader_engine.js.map +1 -0
  11. package/dist/tools/_grader_tool.d.ts +13 -0
  12. package/dist/tools/_grader_tool.d.ts.map +1 -0
  13. package/dist/tools/_grader_tool.js +80 -0
  14. package/dist/tools/_grader_tool.js.map +1 -0
  15. package/dist/tools/_homework.d.ts +18 -0
  16. package/dist/tools/_homework.d.ts.map +1 -0
  17. package/dist/tools/_homework.js +121 -0
  18. package/dist/tools/_homework.js.map +1 -0
  19. package/dist/tools/_lifecycle.d.ts +51 -0
  20. package/dist/tools/_lifecycle.d.ts.map +1 -0
  21. package/dist/tools/_lifecycle.js +124 -0
  22. package/dist/tools/_lifecycle.js.map +1 -0
  23. package/dist/tools/_molecules.d.ts +22 -0
  24. package/dist/tools/_molecules.d.ts.map +1 -0
  25. package/dist/tools/_molecules.js +142 -0
  26. package/dist/tools/_molecules.js.map +1 -0
  27. package/dist/tools/_registry.d.ts.map +1 -1
  28. package/dist/tools/_registry.js +2 -0
  29. package/dist/tools/_registry.js.map +1 -1
  30. package/dist/tools/_types.d.ts +132 -1
  31. package/dist/tools/_types.d.ts.map +1 -1
  32. package/dist/tools/_types.js.map +1 -1
  33. package/dist/tools/memory.d.ts.map +1 -1
  34. package/dist/tools/memory.js +12 -0
  35. package/dist/tools/memory.js.map +1 -1
  36. package/package.json +3 -3
@@ -0,0 +1,80 @@
1
+ /**
2
+ * mneme.grade.answer — the universal grader tool.
3
+ *
4
+ * The AI student calls this AFTER drafting an answer to a user query.
5
+ * The grader runs all 5 Super Sonic algorithms against the draft and
6
+ * returns PASS / WARN / FAIL with concrete rewrite hints.
7
+ *
8
+ * Loop: AI drafts → calls this → on FAIL, AI rewrites → calls this
9
+ * again with retryCount++. Until PASS or maxRetries.
10
+ */
11
+ import { gradeDraft } from "./_grader_engine.js";
12
+ import { homeworkForCategory } from "./_homework.js";
13
+ export const graderTool = {
14
+ name: "mneme.grade.answer",
15
+ category: "meta",
16
+ description: "Grade an AI draft against the homework rubric set by the originating Mneme tool. " +
17
+ "Returns PASS / WARN / FAIL + rewrite hints + per-algorithm verdicts. " +
18
+ "AI student MUST call this after drafting a user-facing answer; on FAIL, AI MUST rewrite using the " +
19
+ "rewriteHints and call grade.answer again with retryCount++. Stop when PASS or maxRetries reached. " +
20
+ "This is the teacher-student loop — Mneme grades the AI's homework before the user ever sees it.",
21
+ triggers: [
22
+ "grade my draft answer",
23
+ "is this answer good enough?",
24
+ "check rubric on draft",
25
+ ],
26
+ inputSchema: {
27
+ type: "object",
28
+ properties: {
29
+ originalQuery: {
30
+ type: "string",
31
+ description: "The user's original question/request",
32
+ },
33
+ aiDraft: {
34
+ type: "string",
35
+ description: "The AI's draft answer to grade",
36
+ },
37
+ sourceCategory: {
38
+ type: "string",
39
+ description: "Which Mneme category produced the data the draft was built from " +
40
+ "(memory | people | audit | forensics | insights | quality | quant | lab | meta). " +
41
+ "Used to pick the right rubric.",
42
+ },
43
+ retryCount: {
44
+ type: "number",
45
+ description: "Which attempt this is (0 for first draft, 1 for first rewrite, …).",
46
+ },
47
+ },
48
+ required: ["originalQuery", "aiDraft", "sourceCategory"],
49
+ },
50
+ handler: async (rt, args) => {
51
+ const originalQuery = String(args["originalQuery"] ?? "");
52
+ const aiDraft = String(args["aiDraft"] ?? "");
53
+ const sourceCategory = String(args["sourceCategory"] ?? "memory");
54
+ const retryCount = typeof args["retryCount"] === "number" ? args["retryCount"] : 0;
55
+ const homework = homeworkForCategory(sourceCategory);
56
+ const result = await gradeDraft({
57
+ cwd: rt.meta.rootPath,
58
+ originalQuery,
59
+ aiDraft,
60
+ homework,
61
+ retryCount,
62
+ });
63
+ return {
64
+ data: result,
65
+ wisdom: result.verdict === "PASS"
66
+ ? `Draft scores ${result.score}/100 — ready to deliver.`
67
+ : result.verdict === "WARN"
68
+ ? `Draft scores ${result.score}/100 — close, but flagged by ${result.algorithmResults.filter((a) => a.verdict === "WARN").length} algorithm(s). Consider one polish pass.`
69
+ : `Draft scores ${result.score}/100 — FAIL. Rewrite using the rewriteHints, then call mneme.grade.answer again with retryCount=${retryCount + 1}.`,
70
+ followUp: result.verdict === "PASS" ? [] : ["mneme.grade.answer"],
71
+ confidence: { level: "high" },
72
+ secondBrain: {
73
+ presentation: result.verdict === "PASS"
74
+ ? "Deliver the draft to the user. Do NOT call other tools unless the user asks a follow-up."
75
+ : "Apply each rewriteHint to the draft. Then call mneme.grade.answer again with the new draft and retryCount incremented. STOP when verdict is PASS or giveUp is true.",
76
+ },
77
+ };
78
+ },
79
+ };
80
+ //# sourceMappingURL=_grader_tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_grader_tool.js","sourceRoot":"","sources":["../../src/tools/_grader_tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGrD,MAAM,CAAC,MAAM,UAAU,GAAc;IACnC,IAAI,EAAE,oBAAoB;IAC1B,QAAQ,EAAE,MAAM;IAChB,WAAW,EACT,mFAAmF;QACnF,uEAAuE;QACvE,oGAAoG;QACpG,oGAAoG;QACpG,iGAAiG;IACnG,QAAQ,EAAE;QACR,uBAAuB;QACvB,6BAA6B;QAC7B,uBAAuB;KACxB;IACD,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,aAAa,EAAE;gBACb,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,sCAAsC;aACpD;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,gCAAgC;aAC9C;YACD,cAAc,EAAE;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,kEAAkE;oBAClE,mFAAmF;oBACnF,gCAAgC;aACnC;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,oEAAoE;aAClF;SACF;QACD,QAAQ,EAAE,CAAC,eAAe,EAAE,SAAS,EAAE,gBAAgB,CAAC;KACzD;IACD,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;QAC1B,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,QAAQ,CAAiB,CAAC;QAClF,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,YAAY,CAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/F,MAAM,QAAQ,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;YAC9B,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ;YACrB,aAAa;YACb,OAAO;YACP,QAAQ;YACR,UAAU;SACX,CAAC,CAAC;QACH,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,MAAM,EACJ,MAAM,CAAC,OAAO,KAAK,MAAM;gBACvB,CAAC,CAAC,gBAAgB,MAAM,CAAC,KAAK,0BAA0B;gBACxD,CAAC,CAAC,MAAM,CAAC,OAAO,KAAK,MAAM;oBAC3B,CAAC,CAAC,gBAAgB,MAAM,CAAC,KAAK,gCAAgC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,MAAM,0CAA0C;oBAC1K,CAAC,CAAC,gBAAgB,MAAM,CAAC,KAAK,mGAAmG,UAAU,GAAG,CAAC,GAAG;YACtJ,QAAQ,EAAE,MAAM,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC;YACjE,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;YAC7B,WAAW,EAAE;gBACX,YAAY,EACV,MAAM,CAAC,OAAO,KAAK,MAAM;oBACvB,CAAC,CAAC,0FAA0F;oBAC5F,CAAC,CAAC,qKAAqK;aAC5K;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Rubric library — what each tool's draft answer must satisfy before
3
+ * being delivered to the user.
4
+ *
5
+ * One rubric per category (9 categories) acts as the DEFAULT — every
6
+ * tool inherits its category's rubric automatically. Tools that need
7
+ * a stricter or looser rubric can override in their handler by
8
+ * setting `secondBrain.homework` directly.
9
+ *
10
+ * The Super Sonic Engine: every Mneme tool response now carries a
11
+ * homework rubric the AI must satisfy. AI drafts → calls
12
+ * mneme.grade.answer → on FAIL, rewrites → loop until PASS. This
13
+ * pattern is unique to Mneme; no other MCP server enforces it.
14
+ */
15
+ import type { Homework, ToolCategory } from "./_types.js";
16
+ /** Build the homework block for a tool, given its category. */
17
+ export declare function homeworkForCategory(category: ToolCategory): Homework;
18
+ //# sourceMappingURL=_homework.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_homework.d.ts","sourceRoot":"","sources":["../../src/tools/_homework.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA+G1D,+DAA+D;AAC/D,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,QAAQ,CAQpE"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Rubric library — what each tool's draft answer must satisfy before
3
+ * being delivered to the user.
4
+ *
5
+ * One rubric per category (9 categories) acts as the DEFAULT — every
6
+ * tool inherits its category's rubric automatically. Tools that need
7
+ * a stricter or looser rubric can override in their handler by
8
+ * setting `secondBrain.homework` directly.
9
+ *
10
+ * The Super Sonic Engine: every Mneme tool response now carries a
11
+ * homework rubric the AI must satisfy. AI drafts → calls
12
+ * mneme.grade.answer → on FAIL, rewrites → loop until PASS. This
13
+ * pattern is unique to Mneme; no other MCP server enforces it.
14
+ */
15
+ /** The 5-axis core requirements every Mneme answer must satisfy.
16
+ * Categories layer their own additional requirements on top. */
17
+ const BASE_REQUIREMENTS = [
18
+ {
19
+ id: "no-hallucinated-citations",
20
+ description: "Every commit hash mentioned must exist in the repo (verified via git rev-parse).",
21
+ weight: 1.0,
22
+ },
23
+ {
24
+ id: "no-empty-wisdom",
25
+ description: "The wisdom field must be a non-empty, non-trivial sentence — not just 'see data'.",
26
+ weight: 0.8,
27
+ },
28
+ {
29
+ id: "confidence-stated",
30
+ description: "The answer must state its confidence (high/medium/low) when claims involve heuristics.",
31
+ weight: 0.6,
32
+ },
33
+ ];
34
+ /** Category-specific requirement layers. */
35
+ const CATEGORY_REQUIREMENTS = {
36
+ memory: [
37
+ { id: "citation-density", description: "≥3 commit citations for any 'why' question, ≥1 for any factual claim.", weight: 1.0 },
38
+ { id: "no-claim-without-citation", description: "Every factual claim about the repo must trace to a specific commit.", weight: 1.0 },
39
+ { id: "summary-bounded", description: "Summary ≤ 200 words; longer needs collapsible details.", weight: 0.5 },
40
+ ],
41
+ people: [
42
+ { id: "no-defamation", description: "Friction/atrophy/nemesis findings framed neutrally — observable behavior, never personal judgment.", weight: 1.0 },
43
+ { id: "atrophy-bounded", description: "Atrophy scores include the 'days since last touch' so reader can verify.", weight: 0.7 },
44
+ { id: "name-the-author", description: "Always identify the specific author (email or name) when applicable.", weight: 0.8 },
45
+ ],
46
+ audit: [
47
+ { id: "all-axes-graded", description: "Trust certificate must score every applicable axis (behavioral / API / tests / perf / narrative).", weight: 1.0 },
48
+ { id: "verdict-matches-axes", description: "Overall PASS/WARN/FAIL must be consistent with the per-axis findings.", weight: 1.0 },
49
+ { id: "remediation-actionable", description: "Every FAIL axis must include a concrete fix recommendation.", weight: 0.9 },
50
+ ],
51
+ forensics: [
52
+ { id: "cwe-cited", description: "Every vuln finding cites its CWE class (e.g. CWE-89, CWE-79).", weight: 1.0 },
53
+ { id: "evidence-quoted", description: "Show the actual line of code that triggered the rule.", weight: 0.9 },
54
+ { id: "false-positive-disclaimer", description: "Always remind the reader that findings are CANDIDATES — verify before action.", weight: 0.7 },
55
+ ],
56
+ insights: [
57
+ { id: "narrative-cohesion", description: "Story / chronicle / time-machine answers must follow chronological + causal order.", weight: 0.8 },
58
+ { id: "ground-in-history", description: "Insights must cite ≥2 commits or PRs as evidence — no speculation without anchor.", weight: 0.9 },
59
+ { id: "actionable", description: "End with a concrete next-step the user can take.", weight: 0.7 },
60
+ ],
61
+ quality: [
62
+ { id: "metric-explained", description: "Every metric stated (atrophy / heartbeat / karma / DNA) must be one-sentence explained inline.", weight: 0.8 },
63
+ { id: "outliers-flagged", description: "Top-3 outliers (most-unusual axes / files / authors) must be highlighted explicitly.", weight: 0.7 },
64
+ ],
65
+ quant: [
66
+ { id: "math-transparent", description: "When a quant metric is reported, briefly state the formula / methodology.", weight: 0.7 },
67
+ { id: "limits-named", description: "Acknowledge the corpus + assumptions the quant ran against.", weight: 0.6 },
68
+ ],
69
+ lab: [
70
+ { id: "plan-auditable", description: "Composed plans show every step + the atom each step calls.", weight: 0.9 },
71
+ { id: "side-effects-named", description: "Plans that hit network / filesystem / git / subprocess declare it upfront.", weight: 1.0 },
72
+ ],
73
+ meta: [
74
+ { id: "scoped", description: "Meta tools (capabilities, doctor, wisdom) keep output scoped to their purpose — no scope creep.", weight: 0.5 },
75
+ ],
76
+ };
77
+ /** Category default rubrics — the writing the AI must produce per category. */
78
+ const CATEGORY_RUBRICS = {
79
+ memory: "Quote the wisdom field directly. Cite ≥3 commits with their short hashes inline. Don't invent commits. " +
80
+ "If <3 citations available, tell the user the answer is best-effort.",
81
+ people: "Frame neutrally — describe observable behavior, never personal character. Always name the specific author. " +
82
+ "Include the heuristic caveat (e.g. 'atrophy is heuristic, not certified knowledge measurement').",
83
+ audit: "Lead with the verdict (PASS/WARN/FAIL) in bold. List every axis with its score + one-line justification. " +
84
+ "For every FAIL axis, give a specific fix the developer can apply right now.",
85
+ forensics: "Open with severity + CWE class. Quote the offending line of code. Always disclose: this is a CANDIDATE, " +
86
+ "verify before acting. Never claim certainty without confirming the rule prior matches the stack.",
87
+ insights: "Tell a story — chronological, causal, anchored to specific commits. End with one concrete action the " +
88
+ "user can take. Avoid speculation that isn't grounded in the diff or PR text.",
89
+ quality: "State the metric, then translate it to plain English. Highlight the top-3 outliers explicitly. " +
90
+ "Skip rendering rows that are within normal range unless asked.",
91
+ quant: "When a number appears, name the formula or method in one phrase. Acknowledge the corpus the metric ran " +
92
+ "against. Quant findings are signals, not verdicts.",
93
+ lab: "If you're emitting a plan, show every step with the atom it calls. Declare side-effects upfront. " +
94
+ "Default to dry-run unless the user explicitly opts into execution.",
95
+ meta: "Stay scoped to the meta-question. The capabilities tool returns a syllabus; the doctor returns env state; " +
96
+ "the wisdom tool returns a meditation. Don't mix scopes.",
97
+ };
98
+ /** All 5 novel grading algorithms applied by default — except for the
99
+ * meta category (where mutation tests would be silly). */
100
+ const DEFAULT_ALGORITHMS_BY_CATEGORY = {
101
+ memory: ["semantic-citation", "adversarial-probe", "claim-graph-mutation"],
102
+ people: ["semantic-citation", "claim-graph-mutation"],
103
+ audit: ["multi-verifier-consensus", "mutation-counterfactual", "claim-graph-mutation"],
104
+ forensics: ["adversarial-probe", "semantic-citation", "multi-verifier-consensus"],
105
+ insights: ["semantic-citation", "claim-graph-mutation", "adversarial-probe"],
106
+ quality: ["claim-graph-mutation", "semantic-citation"],
107
+ quant: ["mutation-counterfactual", "multi-verifier-consensus"],
108
+ lab: ["claim-graph-mutation"],
109
+ meta: [],
110
+ };
111
+ /** Build the homework block for a tool, given its category. */
112
+ export function homeworkForCategory(category) {
113
+ return {
114
+ rubric: CATEGORY_RUBRICS[category],
115
+ requirements: [...BASE_REQUIREMENTS, ...CATEGORY_REQUIREMENTS[category]],
116
+ grader: "mneme.grade.answer",
117
+ maxRetries: 3,
118
+ algorithms: DEFAULT_ALGORITHMS_BY_CATEGORY[category],
119
+ };
120
+ }
121
+ //# sourceMappingURL=_homework.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_homework.js","sourceRoot":"","sources":["../../src/tools/_homework.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Lifecycle tracking — record AI tool invocations + auto-promote frequent
3
+ * compositions into the periodic library.
4
+ *
5
+ * The chain reaction: every tool call lands here. We hash the (set of atoms
6
+ * called within a session window) into a "molecule signature" and count
7
+ * occurrences. When a signature reaches the promotion threshold (≥3 across
8
+ * sessions), we suggest promoting it to a named compound — the user (or AI)
9
+ * picks an alias, and from then on the compound shows up as a single
10
+ * callable in `mneme.lab.library`.
11
+ *
12
+ * Storage: .mneme/mcp-lifecycle.json (NOT the same as library.json — the
13
+ * library is for compose-CLI plans; this file tracks live AI invocations).
14
+ *
15
+ * Race-condition safety: read-modify-write with a temp file rename. Single
16
+ * MCP server per repo at a time; if two run, the second-writer wins, no
17
+ * corruption since the file is small (<100KB even after years of use).
18
+ */
19
+ interface MoleculeSignature {
20
+ /** Sorted atom names joined with "+" for stable key */
21
+ key: string;
22
+ /** Atom names (preserves first-seen order for display) */
23
+ atoms: string[];
24
+ /** Total times this signature has been observed */
25
+ invocations: number;
26
+ /** ISO date of first observation */
27
+ firstSeen: string;
28
+ /** ISO date of last observation */
29
+ lastSeen: string;
30
+ /** Has the user been prompted to save this as a compound? */
31
+ promotionPrompted: boolean;
32
+ /** Saved alias (set when user/AI promotes) */
33
+ promotedAs?: string;
34
+ }
35
+ /** Record that the AI just invoked toolName. If multiple atoms have been
36
+ * called in the same session window, also record them as a molecule
37
+ * signature (the chain reaction trigger). */
38
+ export declare function recordInvocation(repoRoot: string, toolName: string): {
39
+ isNewCombination: boolean;
40
+ invocationCount: number;
41
+ suggestSaveAs?: string;
42
+ };
43
+ /** List molecule signatures observed so far — used by mneme.brain.library.
44
+ * Sorted by frequency descending, then by recency. */
45
+ export declare function listSignatures(repoRoot: string): MoleculeSignature[];
46
+ /** Promote a molecule signature into a named compound. Marks it as promoted
47
+ * in the lifecycle store; the actual compound is written to library.json by
48
+ * the existing periodic.promote() machinery. */
49
+ export declare function markPromoted(repoRoot: string, key: string, alias: string): boolean;
50
+ export {};
51
+ //# sourceMappingURL=_lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_lifecycle.d.ts","sourceRoot":"","sources":["../../src/tools/_lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,UAAU,iBAAiB;IACzB,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,0DAA0D;IAC1D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA0CD;;8CAE8C;AAC9C,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;IACpE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAiDA;AAED;uDACuD;AACvD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAMpE;AAED;;iDAEiD;AACjD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAOlF"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Lifecycle tracking — record AI tool invocations + auto-promote frequent
3
+ * compositions into the periodic library.
4
+ *
5
+ * The chain reaction: every tool call lands here. We hash the (set of atoms
6
+ * called within a session window) into a "molecule signature" and count
7
+ * occurrences. When a signature reaches the promotion threshold (≥3 across
8
+ * sessions), we suggest promoting it to a named compound — the user (or AI)
9
+ * picks an alias, and from then on the compound shows up as a single
10
+ * callable in `mneme.lab.library`.
11
+ *
12
+ * Storage: .mneme/mcp-lifecycle.json (NOT the same as library.json — the
13
+ * library is for compose-CLI plans; this file tracks live AI invocations).
14
+ *
15
+ * Race-condition safety: read-modify-write with a temp file rename. Single
16
+ * MCP server per repo at a time; if two run, the second-writer wins, no
17
+ * corruption since the file is small (<100KB even after years of use).
18
+ */
19
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync } from "node:fs";
20
+ import { join, dirname } from "node:path";
21
+ const PROMOTION_THRESHOLD = 3;
22
+ const SESSION_WINDOW_MS = 5 * 60_000; // 5 minutes
23
+ /** In-memory window tracker — accumulates atoms called within the same
24
+ * AI session before flushing to the persistent store. */
25
+ let currentSession = {
26
+ atoms: new Set(),
27
+ lastTouch: 0,
28
+ };
29
+ function lifecyclePath(repoRoot) {
30
+ return join(repoRoot, ".mneme", "mcp-lifecycle.json");
31
+ }
32
+ function readStore(repoRoot) {
33
+ const p = lifecyclePath(repoRoot);
34
+ if (!existsSync(p))
35
+ return { version: 1, signatures: {} };
36
+ try {
37
+ const raw = readFileSync(p, "utf8");
38
+ const parsed = JSON.parse(raw);
39
+ if (parsed.version !== 1)
40
+ return { version: 1, signatures: {} };
41
+ return parsed;
42
+ }
43
+ catch {
44
+ return { version: 1, signatures: {} };
45
+ }
46
+ }
47
+ function writeStore(repoRoot, store) {
48
+ const p = lifecyclePath(repoRoot);
49
+ if (!existsSync(dirname(p)))
50
+ mkdirSync(dirname(p), { recursive: true });
51
+ const tmp = p + ".tmp";
52
+ writeFileSync(tmp, JSON.stringify(store, null, 2) + "\n", "utf8");
53
+ renameSync(tmp, p);
54
+ }
55
+ /** Record that the AI just invoked toolName. If multiple atoms have been
56
+ * called in the same session window, also record them as a molecule
57
+ * signature (the chain reaction trigger). */
58
+ export function recordInvocation(repoRoot, toolName) {
59
+ const now = Date.now();
60
+ // Reset session window if too much time has passed
61
+ if (now - currentSession.lastTouch > SESSION_WINDOW_MS) {
62
+ currentSession = { atoms: new Set(), lastTouch: now };
63
+ }
64
+ currentSession.atoms.add(toolName);
65
+ currentSession.lastTouch = now;
66
+ // Only record signatures when ≥2 atoms in window — single-atom calls
67
+ // are just normal tool use, not a molecule.
68
+ if (currentSession.atoms.size < 2) {
69
+ return { isNewCombination: false, invocationCount: 1 };
70
+ }
71
+ const atoms = Array.from(currentSession.atoms).sort();
72
+ const key = atoms.join("+");
73
+ const store = readStore(repoRoot);
74
+ const existing = store.signatures[key];
75
+ const today = new Date().toISOString();
76
+ if (!existing) {
77
+ store.signatures[key] = {
78
+ key,
79
+ atoms,
80
+ invocations: 1,
81
+ firstSeen: today,
82
+ lastSeen: today,
83
+ promotionPrompted: false,
84
+ };
85
+ writeStore(repoRoot, store);
86
+ return { isNewCombination: true, invocationCount: 1 };
87
+ }
88
+ existing.invocations++;
89
+ existing.lastSeen = today;
90
+ let suggestSaveAs;
91
+ if (existing.invocations >= PROMOTION_THRESHOLD && !existing.promotionPrompted && !existing.promotedAs) {
92
+ existing.promotionPrompted = true;
93
+ suggestSaveAs = `compound_${atoms[0]?.split(".").slice(-1)[0] ?? "x"}_${atoms.length}atoms`;
94
+ }
95
+ writeStore(repoRoot, store);
96
+ return {
97
+ isNewCombination: false,
98
+ invocationCount: existing.invocations,
99
+ suggestSaveAs,
100
+ };
101
+ }
102
+ /** List molecule signatures observed so far — used by mneme.brain.library.
103
+ * Sorted by frequency descending, then by recency. */
104
+ export function listSignatures(repoRoot) {
105
+ const store = readStore(repoRoot);
106
+ return Object.values(store.signatures).sort((a, b) => {
107
+ if (b.invocations !== a.invocations)
108
+ return b.invocations - a.invocations;
109
+ return b.lastSeen.localeCompare(a.lastSeen);
110
+ });
111
+ }
112
+ /** Promote a molecule signature into a named compound. Marks it as promoted
113
+ * in the lifecycle store; the actual compound is written to library.json by
114
+ * the existing periodic.promote() machinery. */
115
+ export function markPromoted(repoRoot, key, alias) {
116
+ const store = readStore(repoRoot);
117
+ const sig = store.signatures[key];
118
+ if (!sig)
119
+ return false;
120
+ sig.promotedAs = alias;
121
+ writeStore(repoRoot, store);
122
+ return true;
123
+ }
124
+ //# sourceMappingURL=_lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_lifecycle.js","sourceRoot":"","sources":["../../src/tools/_lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Molecule recipes — pre-defined atom combinations that form named molecules.
3
+ *
4
+ * Architectural role:
5
+ * - Atoms = individual MCP tools (mneme.people.atrophy, mneme.audit.certify, …)
6
+ * - Molecules = named combinations of atoms that solve a higher-order question
7
+ * - Compounds = molecules promoted into the library via repeated use
8
+ *
9
+ * Each tool's `secondBrain.compose` field surfaces the molecules that include
10
+ * its atom — so the AI sees "if you just ran X, the natural next is to compose
11
+ * X+Y+Z = molecule M". This triggers the chain-reaction of wisdom.
12
+ *
13
+ * The 20 molecules below cover the most-asked higher-order questions in
14
+ * software-engineering management, security review, and AI-session audit.
15
+ */
16
+ import type { ComposeSuggestion } from "./_types.js";
17
+ /** All known molecules. Each lists the atoms that compose it + when to fire. */
18
+ export declare const MOLECULES: ComposeSuggestion[];
19
+ /** Find all molecules whose atoms include the given tool name.
20
+ * Used by tools to populate their `secondBrain.compose` field. */
21
+ export declare function moleculesContaining(atomName: string): ComposeSuggestion[];
22
+ //# sourceMappingURL=_molecules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_molecules.d.ts","sourceRoot":"","sources":["../../src/tools/_molecules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,gFAAgF;AAChF,eAAO,MAAM,SAAS,EAAE,iBAAiB,EAkIxC,CAAC;AAEF;mEACmE;AACnE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAEzE"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Molecule recipes — pre-defined atom combinations that form named molecules.
3
+ *
4
+ * Architectural role:
5
+ * - Atoms = individual MCP tools (mneme.people.atrophy, mneme.audit.certify, …)
6
+ * - Molecules = named combinations of atoms that solve a higher-order question
7
+ * - Compounds = molecules promoted into the library via repeated use
8
+ *
9
+ * Each tool's `secondBrain.compose` field surfaces the molecules that include
10
+ * its atom — so the AI sees "if you just ran X, the natural next is to compose
11
+ * X+Y+Z = molecule M". This triggers the chain-reaction of wisdom.
12
+ *
13
+ * The 20 molecules below cover the most-asked higher-order questions in
14
+ * software-engineering management, security review, and AI-session audit.
15
+ */
16
+ /** All known molecules. Each lists the atoms that compose it + when to fire. */
17
+ export const MOLECULES = [
18
+ // ─────── PEOPLE / KNOWLEDGE / TEAM HEALTH ───────
19
+ {
20
+ molecule: "succession_plan",
21
+ atoms: ["mneme.people.atrophy", "mneme.people.bus_factor", "mneme.people.telepathy"],
22
+ when: "User asks about org-risk, handover, what happens if X leaves, knowledge transfer, " +
23
+ "single points of failure, or backup engineers.",
24
+ example: "Atrophy says Alice's auth knowledge is 28/100 (fading). Bus-factor confirms she owns " +
25
+ "78% of auth files. Telepathy suggests Bob writes auth-shaped code without co-authoring " +
26
+ "Alice — recommended pair-onboarding target.",
27
+ },
28
+ {
29
+ molecule: "knowledge_health_check",
30
+ atoms: ["mneme.people.atrophy", "mneme.people.passport", "mneme.quality.repo_mri"],
31
+ when: "Quarterly review, before a reorg, or when user asks 'how healthy is the team?'.",
32
+ example: "Combine atrophy heatmap + per-engineer passport + 20-axis MRI into one dashboard.",
33
+ },
34
+ {
35
+ molecule: "onboarding_dossier",
36
+ atoms: ["mneme.insights.mirror", "mneme.people.who_knows", "mneme.insights.story", "mneme.people.passport"],
37
+ when: "New hire arrives, or someone asks 'how do I get up to speed on X?'.",
38
+ },
39
+ {
40
+ molecule: "team_friction_diagnosis",
41
+ atoms: ["mneme.people.nemesis", "mneme.insights.regret", "mneme.people.lineage"],
42
+ when: "User asks 'where is friction?', 'who's stepping on whom?', 'rewrite churn'.",
43
+ },
44
+ // ─────── AI COMMIT SAFETY / AUDIT ───────
45
+ {
46
+ molecule: "ai_commit_check",
47
+ atoms: ["mneme.audit.trace", "mneme.audit.verify", "mneme.audit.certify"],
48
+ when: "Before merging an AI-generated commit, before a CI gate, or at PR review time.",
49
+ example: "Trace identifies the AI tool (Claude Code / Cursor / Codex). Verify catches narrative-vs-diff " +
50
+ "drift. Certify gives 5-axis pass/warn/fail.",
51
+ },
52
+ {
53
+ molecule: "compliance_evidence_pack",
54
+ atoms: ["mneme.audit.report", "mneme.audit.ledger", "mneme.audit.deps", "mneme.forensics.vulns"],
55
+ when: "EU AI Act 2026 evidence request, SOX/SOC2 quarterly, or external audit prep.",
56
+ },
57
+ // ─────── REFACTOR / SHIP SAFETY ───────
58
+ {
59
+ molecule: "refactor_safety_check",
60
+ atoms: ["mneme.insights.premortem", "mneme.memory.blast", "mneme.people.atrophy"],
61
+ when: "User proposes a refactor, asks 'is this safe?', 'has this been tried?', or wants to estimate " +
62
+ "blast radius before merge.",
63
+ example: "Premortem says 78% regret-risk based on 7 of 9 similar attempts. Blast names 3 incident-prone " +
64
+ "files in the diff. Atrophy warns the file owner is 28/100 fresh — knowledge gap.",
65
+ },
66
+ {
67
+ molecule: "regret_pattern_review",
68
+ atoms: ["mneme.insights.regret", "mneme.insights.paradox", "mneme.insights.crystal_ball"],
69
+ when: "Quarterly retro, post-mortem, or before deciding whether to attempt a contested refactor.",
70
+ },
71
+ {
72
+ molecule: "deploy_gate",
73
+ atoms: ["mneme.audit.certify", "mneme.forensics.vulns", "mneme.audit.deps", "mneme.insights.crystal_ball"],
74
+ when: "CI gate before production deploy, release candidate review.",
75
+ },
76
+ // ─────── SECURITY / FORENSICS ───────
77
+ {
78
+ molecule: "security_review",
79
+ atoms: ["mneme.forensics.vulns", "mneme.audit.deps", "mneme.forensics.anomaly"],
80
+ when: "Security review of a feature, before pen-test, or after a suspected incident.",
81
+ },
82
+ {
83
+ molecule: "incident_attribution",
84
+ atoms: ["mneme.forensics.match", "mneme.forensics.attribute", "mneme.forensics.anomaly"],
85
+ when: "After a suspicious commit lands, during incident response, or insider-threat review.",
86
+ },
87
+ {
88
+ molecule: "vulnerability_triage",
89
+ atoms: ["mneme.forensics.vulns", "mneme.forensics.show", "mneme.audit.conscience"],
90
+ when: "Reviewing a fresh batch of vuln findings — score, inspect, suppress false positives.",
91
+ },
92
+ // ─────── STORY / NARRATIVE / DECISIONS ───────
93
+ {
94
+ molecule: "decision_archaeology",
95
+ atoms: ["mneme.memory.ask", "mneme.insights.decisions", "mneme.insights.story"],
96
+ when: "User asks 'why does X exist?', 'what was the rationale for Y?', or wants ADR-style narrative.",
97
+ example: "Cited Q&A → ADR list → multi-act narrative arc.",
98
+ },
99
+ {
100
+ molecule: "file_archaeology",
101
+ atoms: ["mneme.memory.why", "mneme.insights.time_machine", "mneme.quality.palimpsest", "mneme.people.lineage"],
102
+ when: "User wants the full life story of a file or a single line of code.",
103
+ },
104
+ {
105
+ molecule: "expert_finder",
106
+ atoms: ["mneme.people.who_knows", "mneme.people.passport", "mneme.people.atrophy"],
107
+ when: "User asks 'who can help me with X?', 'who should review this PR?'.",
108
+ },
109
+ // ─────── QUALITY / DEBT ───────
110
+ {
111
+ molecule: "tech_debt_audit",
112
+ atoms: ["mneme.quality.karma", "mneme.people.promise", "mneme.insights.ghost", "mneme.insights.fossil"],
113
+ when: "Quarterly tech-debt review, sprint planning for cleanup, or before a major refactor.",
114
+ },
115
+ {
116
+ molecule: "code_quality_dashboard",
117
+ atoms: ["mneme.quality.repo_mri", "mneme.quality.heartbeat", "mneme.insights.runaway", "mneme.insights.drift"],
118
+ when: "Engineering manager dashboard, monthly health check, or VP-of-eng update.",
119
+ },
120
+ // ─────── PREDICTION / FORESIGHT ───────
121
+ {
122
+ molecule: "release_readiness",
123
+ atoms: ["mneme.audit.certify", "mneme.insights.crystal_ball", "mneme.memory.blast", "mneme.forensics.vulns"],
124
+ when: "Final go/no-go before shipping a release.",
125
+ },
126
+ {
127
+ molecule: "next_quarter_risk_map",
128
+ atoms: ["mneme.people.atrophy", "mneme.insights.oracle", "mneme.quant.black_swan", "mneme.quality.heartbeat"],
129
+ when: "Strategic planning — what's likely to break, who's at risk of forgetting, where are the tail risks?",
130
+ },
131
+ {
132
+ molecule: "moneyball_review",
133
+ atoms: ["mneme.quant.moneyball", "mneme.people.influence", "mneme.people.passport"],
134
+ when: "Compensation review, promotion committee, identifying undervalued contributors.",
135
+ },
136
+ ];
137
+ /** Find all molecules whose atoms include the given tool name.
138
+ * Used by tools to populate their `secondBrain.compose` field. */
139
+ export function moleculesContaining(atomName) {
140
+ return MOLECULES.filter((m) => m.atoms.includes(atomName));
141
+ }
142
+ //# sourceMappingURL=_molecules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_molecules.js","sourceRoot":"","sources":["../../src/tools/_molecules.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"_registry.d.ts","sourceRoot":"","sources":["../../src/tools/_registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAc3D;sEACsE;AACtE,wBAAgB,aAAa,IAAI,SAAS,EAAE,CAc3C;AAED,mDAAmD;AACnD,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CASrD;AAED,uEAAuE;AACvE,wBAAgB,eAAe,IAAI,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,CAAC,CAOhE"}
1
+ {"version":3,"file":"_registry.d.ts","sourceRoot":"","sources":["../../src/tools/_registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAe3D;sEACsE;AACtE,wBAAgB,aAAa,IAAI,SAAS,EAAE,CAe3C;AAED,mDAAmD;AACnD,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CASrD;AAED,uEAAuE;AACvE,wBAAgB,eAAe,IAAI,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,CAAC,CAOhE"}
@@ -16,11 +16,13 @@ import { labTools } from "./lab.js";
16
16
  import { metaTools } from "./meta.js";
17
17
  import { capabilitiesTool } from "./_capabilities.js";
18
18
  import { smartDoTool } from "./_smart_do.js";
19
+ import { graderTool } from "./_grader_tool.js";
19
20
  /** All Mneme tools, in display order. The capabilities syllabus comes first
20
21
  * so AI clients that read tool lists top-down see it immediately. */
21
22
  export function buildAllTools() {
22
23
  return [
23
24
  capabilitiesTool,
25
+ graderTool,
24
26
  smartDoTool,
25
27
  ...memoryTools,
26
28
  ...peopleTools,
@@ -1 +1 @@
1
- {"version":3,"file":"_registry.js","sourceRoot":"","sources":["../../src/tools/_registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C;sEACsE;AACtE,MAAM,UAAU,aAAa;IAC3B,OAAO;QACL,gBAAgB;QAChB,WAAW;QACX,GAAG,WAAW;QACd,GAAG,WAAW;QACd,GAAG,UAAU;QACb,GAAG,cAAc;QACjB,GAAG,aAAa;QAChB,GAAG,YAAY;QACf,GAAG,UAAU;QACb,GAAG,QAAQ;QACX,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,YAAY;IAC1B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAqB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,EAAE,CAAC;QAChC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,IAAI,GAAG,EAA6B,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,EAAE,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClD,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"_registry.js","sourceRoot":"","sources":["../../src/tools/_registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;sEACsE;AACtE,MAAM,UAAU,aAAa;IAC3B,OAAO;QACL,gBAAgB;QAChB,UAAU;QACV,WAAW;QACX,GAAG,WAAW;QACd,GAAG,WAAW;QACd,GAAG,UAAU;QACb,GAAG,cAAc;QACjB,GAAG,aAAa;QAChB,GAAG,YAAY;QACf,GAAG,UAAU;QACb,GAAG,QAAQ;QACX,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,YAAY;IAC1B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAqB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,EAAE,CAAC;QAChC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,IAAI,GAAG,EAA6B,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,EAAE,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClD,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}