@mneme-ai/core 1.90.0 → 1.91.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.
@@ -1 +1 @@
1
- {"version":3,"file":"soul_prompt.d.ts","sourceRoot":"","sources":["../../src/genesplice/soul_prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAMpF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,cAAc,CAAC;IACxB;uEACmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;2CAGuC;IACvC,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAcD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,CA+DvE;AAED,MAAM,WAAW,gBAAgB;IAC/B,qBAAqB;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gCAAgC;IAChC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,OAAO,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;CAC9D;AAED;;0CAE0C;AAC1C,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAsDrF"}
1
+ {"version":3,"file":"soul_prompt.d.ts","sourceRoot":"","sources":["../../src/genesplice/soul_prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAOpF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,cAAc,CAAC;IACxB;uEACmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;2CAGuC;IACvC,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAcD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,CAqEvE;AAED,MAAM,WAAW,gBAAgB;IAC/B,qBAAqB;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gCAAgC;IAChC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,OAAO,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;CAC9D;AAED;;0CAE0C;AAC1C,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAsDrF"}
@@ -46,6 +46,7 @@ import { renderVoiceDirective } from "../seamless/voice_directive.js";
46
46
  import { renderDictionary } from "../lattice/dictionary.js";
47
47
  import { renderRelayBlock } from "../conduit/relay_prompt.js";
48
48
  import { renderVersionGate } from "../conduit/version_gate.js";
49
+ import { renderHomunculusRequest } from "../abyss/homunculus.js";
49
50
  const TOK_PER_WORD = 1.3;
50
51
  function estTokens(s) {
51
52
  return Math.round(s.split(/\s+/).filter(Boolean).length * TOK_PER_WORD);
@@ -88,6 +89,12 @@ export function compressToSoulPrompt(input) {
88
89
  "",
89
90
  renderVersionGate(capsule.createdAt),
90
91
  "",
92
+ // v1.91: embed HOMUNCULUS request by default so receiving AIs know
93
+ // to emit a structured RETURN block the user can paste back to the
94
+ // editor AI for actual Mneme tool execution. Closes the cycle:
95
+ // editor → web (memory) → web suggests → user pastes back → editor executes.
96
+ renderHomunculusRequest({ originatorVendor: capsule.originVendor, ask: ["decisions", "reasoning", "next-actions"] }),
97
+ "",
91
98
  `## Origin`,
92
99
  `vendor=${capsule.originVendor} capsule=${capsule.id} fingerprint=${capsule.repoFingerprint} createdAt=${capsule.createdAt}`,
93
100
  "",
@@ -1 +1 @@
1
- {"version":3,"file":"soul_prompt.js","sourceRoot":"","sources":["../../src/genesplice/soul_prompt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"soul_prompt.js","sourceRoot":"","sources":["../../src/genesplice/soul_prompt.ts"],"names":[],"mappings":"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"}
@@ -15,4 +15,5 @@ export * from "./handoff.js";
15
15
  export * from "./tunnel.js";
16
16
  export * from "./multi_paste.js";
17
17
  export * from "./resource_hints.js";
18
+ export * from "./page_renderer.js";
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rainbow/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rainbow/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
@@ -15,4 +15,5 @@ export * from "./handoff.js";
15
15
  export * from "./tunnel.js";
16
16
  export * from "./multi_paste.js";
17
17
  export * from "./resource_hints.js";
18
+ export * from "./page_renderer.js";
18
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rainbow/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rainbow/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * v1.91.0 -- RAINBOW: PC + mobile page renderers.
3
+ *
4
+ * Was previously inline JS inside `.brain-show*.mjs` scripts. v1.91
5
+ * promotes them into proper, testable, reusable modules.
6
+ *
7
+ * renderMobilePage({ soulText, lang })
8
+ * → HTML page served from LAN/tunnel; phone scans → opens here
9
+ * → green Share button + blue Copy button (3-tier fallback)
10
+ * → bilingual EN/TH toggle
11
+ * → honest capability matrix (paste vs editor-AI MCP truth)
12
+ *
13
+ * renderPcPage({ primaryUrl, label, note, soulTokens, hasTunnel })
14
+ * → Page that opens in PC default browser
15
+ * → ONE big primary QR (no second-QR confusion)
16
+ * → STOP button (no Ctrl+C jargon)
17
+ * → bilingual toggle
18
+ *
19
+ * Both pages: zero external CSS/JS deps. Single-file output.
20
+ */
21
+ export interface MobilePageInput {
22
+ soulText: string;
23
+ /** Optional override for default lang. Default "en" with toggle. */
24
+ defaultLang?: "en" | "th";
25
+ }
26
+ export interface PcPageInput {
27
+ primaryUrl: string;
28
+ /** Channel label (e.g. "Same Wi-Fi · 1 tap" / "Works ANYWHERE · 1 tap"). */
29
+ label: {
30
+ en: string;
31
+ th: string;
32
+ };
33
+ /** Channel note (e.g. "Phone MUST be on the SAME WiFi"). */
34
+ note: {
35
+ en: string;
36
+ th: string;
37
+ };
38
+ /** Soul prompt size in tokens (for footer). */
39
+ soulTokens: number;
40
+ /** True if cloudflared tunnel is in use (footer mention). */
41
+ hasTunnel: boolean;
42
+ /** True if a paste fallback exists. */
43
+ hasPaste: boolean;
44
+ defaultLang?: "en" | "th";
45
+ }
46
+ export declare function renderMobilePage(input: MobilePageInput): string;
47
+ export declare function renderPcPage(input: PcPageInput): string;
48
+ //# sourceMappingURL=page_renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page_renderer.d.ts","sourceRoot":"","sources":["../../src/rainbow/page_renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,4DAA4D;IAC5D,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAC3B;AAmBD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAuG/D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAkFvD"}
@@ -0,0 +1,221 @@
1
+ /**
2
+ * v1.91.0 -- RAINBOW: PC + mobile page renderers.
3
+ *
4
+ * Was previously inline JS inside `.brain-show*.mjs` scripts. v1.91
5
+ * promotes them into proper, testable, reusable modules.
6
+ *
7
+ * renderMobilePage({ soulText, lang })
8
+ * → HTML page served from LAN/tunnel; phone scans → opens here
9
+ * → green Share button + blue Copy button (3-tier fallback)
10
+ * → bilingual EN/TH toggle
11
+ * → honest capability matrix (paste vs editor-AI MCP truth)
12
+ *
13
+ * renderPcPage({ primaryUrl, label, note, soulTokens, hasTunnel })
14
+ * → Page that opens in PC default browser
15
+ * → ONE big primary QR (no second-QR confusion)
16
+ * → STOP button (no Ctrl+C jargon)
17
+ * → bilingual toggle
18
+ *
19
+ * Both pages: zero external CSS/JS deps. Single-file output.
20
+ */
21
+ function jsSafe(s) {
22
+ return JSON.stringify(s).replace(/<\/(script)/gi, "<\\/$1");
23
+ }
24
+ function escapeHtml(s) {
25
+ return s
26
+ .replace(/&/g, "&amp;")
27
+ .replace(/</g, "&lt;")
28
+ .replace(/>/g, "&gt;")
29
+ .replace(/"/g, "&quot;")
30
+ .replace(/'/g, "&#39;");
31
+ }
32
+ function buildQrUrl(payload, size = 360) {
33
+ return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&format=svg&margin=10&data=${encodeURIComponent(payload)}`;
34
+ }
35
+ export function renderMobilePage(input) {
36
+ const lang = input.defaultLang ?? "en";
37
+ return `<!doctype html><html lang="${lang}"><head>
38
+ <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
39
+ <title>Mneme</title>
40
+ <style>
41
+ *{box-sizing:border-box;margin:0;padding:0}
42
+ body{font-family:-apple-system,sans-serif;background:#1abc9c;color:#fff;min-height:100vh;padding:24px 18px}
43
+ .wrap{max-width:540px;margin:0 auto;display:flex;flex-direction:column;gap:18px}
44
+ h1{font-size:32px;text-align:center;font-weight:800}
45
+ .lang{position:fixed;top:14px;right:14px;background:rgba(0,0,0,0.4);border:0;color:#fff;padding:10px 16px;border-radius:8px;font-weight:700;cursor:pointer;font-size:15px}
46
+ .btn{width:100%;background:#fff;color:#16a085;border:0;padding:24px;border-radius:14px;font-weight:800;font-size:22px;cursor:pointer;box-shadow:0 8px 20px rgba(0,0,0,0.3)}
47
+ .btn:active{transform:scale(0.97)}
48
+ .btn.blue{background:#3498db;color:#fff}
49
+ .step{background:rgba(0,0,0,0.25);padding:18px;border-radius:12px;font-size:18px;line-height:1.6}
50
+ .matrix{background:rgba(0,0,0,0.3);padding:18px;border-radius:12px;font-size:14px;line-height:1.6}
51
+ .matrix h3{font-size:17px;margin-bottom:10px}
52
+ .matrix table{width:100%;border-collapse:collapse}
53
+ .matrix td{padding:8px 4px;border-bottom:1px solid rgba(255,255,255,0.15)}
54
+ .matrix td:last-child{text-align:center;font-weight:700}
55
+ .ok{display:none;background:#27ae60;padding:18px;border-radius:12px;text-align:center;font-weight:800;font-size:17px}
56
+ textarea{width:100%;height:1px;opacity:0;position:absolute;left:-9999px}
57
+ .preview{background:rgba(0,0,0,0.4);padding:14px;border-radius:8px;font-family:monospace;font-size:11px;line-height:1.4;max-height:140px;overflow:auto;white-space:pre-wrap;word-break:break-word;-webkit-user-select:all;user-select:all}
58
+ details summary{cursor:pointer;padding:14px;background:rgba(0,0,0,0.25);border-radius:10px;font-weight:700;font-size:16px}
59
+ .grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
60
+ .grid a{display:block;background:rgba(255,255,255,0.18);padding:16px;border-radius:10px;text-align:center;text-decoration:none;color:#fff;font-weight:700;font-size:15px}
61
+ </style></head><body>
62
+ <button class="lang" id="lang">ไทย</button>
63
+ <div class="wrap">
64
+ <h1 data-en="Mneme handoff" data-th="ส่งสมอง Mneme"></h1>
65
+ <div class="step" data-en="Tap GREEN to send. If share menu doesn't appear, tap BLUE COPY then paste in any AI." data-th="กดปุ่มเขียวเพื่อส่ง. ถ้าไม่มี share menu ขึ้น กด COPY สีฟ้าแล้ว paste ใน AI"></div>
66
+ <button id="s" class="btn">📤 Send to AI app</button>
67
+ <div id="ok" class="ok" data-en="✓ Sent! Open your AI to check." data-th="✓ ส่งแล้ว เปิด AI ดู"></div>
68
+ <button id="c" class="btn blue">📋 Copy soul prompt</button>
69
+ <details>
70
+ <summary data-en="🔧 Backup: long-press to copy" data-th="🔧 สำรอง: กดค้างเพื่อก๊อป"></summary>
71
+ <div style="padding:10px 0;font-size:14px" data-en="If both buttons fail, long-press the box → Select All → Copy:" data-th="ถ้าปุ่มทั้งสองไม่ work กดค้างกล่องล่าง → Select All → Copy:"></div>
72
+ <div class="preview" id="prev"></div>
73
+ </details>
74
+ <div class="grid">
75
+ <a href="https://chatgpt.com/" target="_blank">🟢 ChatGPT</a>
76
+ <a href="https://gemini.google.com/app" target="_blank">🔵 Gemini</a>
77
+ <a href="https://claude.ai/new" target="_blank">🟣 Claude</a>
78
+ <a href="https://www.perplexity.ai/" target="_blank">⚪ Perplexity</a>
79
+ </div>
80
+ <div class="matrix">
81
+ <h3 data-en="🎯 What this AI can do AFTER you paste" data-th="🎯 หลัง paste แล้ว AI ทำอะไรได้บ้าง"></h3>
82
+ <table>
83
+ <tr><td data-en="Read this conversation" data-th="อ่านบทสนทนานี้"></td><td>✅</td></tr>
84
+ <tr><td data-en="Continue discussing it" data-th="คุยต่อจากเดิม"></td><td>✅</td></tr>
85
+ <tr><td data-en="Understand recent decisions" data-th="เข้าใจการตัดสินใจล่าสุด"></td><td>✅</td></tr>
86
+ <tr><td data-en="Suggest next actions back" data-th="เสนอ next actions กลับมา"></td><td>✅</td></tr>
87
+ <tr><td data-en="Call Mneme MCP tools (live)" data-th="เรียก MCP tools จริง"></td><td>❌</td></tr>
88
+ <tr><td data-en="Read your .mneme/ files" data-th="อ่านไฟล์ .mneme/ บน PC"></td><td>❌</td></tr>
89
+ <tr><td data-en="True real-time sync" data-th="sync แบบ real-time จริง"></td><td>❌</td></tr>
90
+ </table>
91
+ <div style="margin-top:12px;padding:12px;background:rgba(255,255,255,0.1);border-radius:8px;font-size:13px;line-height:1.5">
92
+ <span data-en="The soul prompt gives the AI MEMORY (read-only). The HOMUNCULUS request inside it asks the AI to emit a HOMUNCULUS RETURN block with suggestions you paste BACK to your editor AI for execution. Web AI = brain. Editor AI = hands. You = courier." data-th="soul prompt ให้ AI เห็น MEMORY (อ่านอย่างเดียว). HOMUNCULUS request ที่อยู่ในนั้นจะขอให้ AI ตอบกลับเป็น HOMUNCULUS RETURN block ที่คุณ paste กลับไป editor AI เพื่อ execute. Web AI = สมอง. Editor AI = มือ. คุณ = courier"></span>
93
+ </div>
94
+ </div>
95
+ </div>
96
+ <textarea id="ta"></textarea>
97
+ <script>
98
+ const SOUL = ${jsSafe(input.soulText)};
99
+ let lang = ${JSON.stringify(lang)};
100
+ function applyLang() {
101
+ document.querySelectorAll("[data-en]").forEach(el => { el.textContent = el.dataset[lang] || el.dataset.en; });
102
+ document.getElementById("lang").textContent = lang === "en" ? "ไทย" : "EN";
103
+ document.documentElement.lang = lang;
104
+ }
105
+ applyLang();
106
+ document.getElementById("lang").onclick = () => { lang = lang === "en" ? "th" : "en"; applyLang(); };
107
+ document.getElementById("prev").textContent = SOUL;
108
+ document.getElementById("ta").value = SOUL;
109
+ document.getElementById("s").onclick = async () => {
110
+ if (navigator.share) {
111
+ try { await navigator.share({ text: SOUL, title: "Mneme" }); document.getElementById("ok").style.display = "block"; return; }
112
+ catch (e) {}
113
+ }
114
+ copySoul();
115
+ };
116
+ function copySoul() {
117
+ if (navigator.clipboard && window.isSecureContext) {
118
+ navigator.clipboard.writeText(SOUL).then(() => {
119
+ document.getElementById("c").textContent = lang === "th" ? "✓ ก๊อปแล้ว เปิด AI app paste เลย" : "✓ Copied! Open AI app and paste.";
120
+ }).catch(() => fallbackCopy());
121
+ } else { fallbackCopy(); }
122
+ }
123
+ function fallbackCopy() {
124
+ const ta = document.getElementById("ta");
125
+ ta.value = SOUL; ta.style.opacity = "1"; ta.style.position = "static"; ta.style.height = "60px"; ta.style.left = "0";
126
+ ta.focus(); ta.select(); ta.setSelectionRange(0, SOUL.length);
127
+ try {
128
+ if (document.execCommand("copy")) {
129
+ document.getElementById("c").textContent = lang === "th" ? "✓ ก๊อปแล้ว" : "✓ Copied!";
130
+ ta.style.opacity = "0"; ta.style.position = "absolute"; ta.style.height = "1px"; ta.style.left = "-9999px";
131
+ return;
132
+ }
133
+ } catch (e) {}
134
+ document.getElementById("c").textContent = lang === "th" ? "⬇ กดค้างกล่อง → Select All → Copy" : "⬇ Long-press box → Select All → Copy";
135
+ }
136
+ document.getElementById("c").onclick = copySoul;
137
+ </script></body></html>`;
138
+ }
139
+ export function renderPcPage(input) {
140
+ const lang = input.defaultLang ?? "en";
141
+ const labelEn = escapeHtml(input.label.en);
142
+ const labelTh = escapeHtml(input.label.th);
143
+ const noteEn = escapeHtml(input.note.en);
144
+ const noteTh = escapeHtml(input.note.th);
145
+ const url = escapeHtml(input.primaryUrl);
146
+ const tunnelMention = input.hasTunnel ? "Cloudflare tunnel + " : "";
147
+ const pasteMention = input.hasPaste ? " · paste fallback" : "";
148
+ return `<!doctype html><html lang="${lang}"><head>
149
+ <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
150
+ <title>Mneme — Send brain to phone</title>
151
+ <style>
152
+ *{box-sizing:border-box;margin:0;padding:0}
153
+ body{font-family:-apple-system,"Segoe UI",sans-serif;background:linear-gradient(135deg,#1abc9c 0%,#16a085 50%,#2c3e50 100%);color:#fff;min-height:100vh;padding:32px 24px}
154
+ .wrap{max-width:760px;margin:0 auto;display:flex;flex-direction:column;align-items:center;gap:28px}
155
+ .lang-btn,.stop-btn{position:fixed;top:18px;background:rgba(0,0,0,0.4);border:0;color:#fff;padding:12px 20px;border-radius:10px;font-weight:700;font-size:16px;cursor:pointer;z-index:99}
156
+ .lang-btn{right:18px}
157
+ .stop-btn{right:130px;background:#c0392b}
158
+ .stop-btn:hover{background:#e74c3c}
159
+ h1{font-size:46px;text-align:center;font-weight:800}
160
+ .tagline{font-size:22px;opacity:0.92;text-align:center;line-height:1.5;max-width:600px}
161
+ .primary{background:rgba(255,255,255,0.1);border:2px solid rgba(255,255,255,0.25);border-radius:24px;padding:32px;display:flex;flex-direction:column;align-items:center;gap:18px;width:100%;max-width:520px;box-shadow:0 24px 70px rgba(0,0,0,0.4)}
162
+ .pill{display:inline-block;background:#27ae60;padding:10px 22px;border-radius:99px;font-size:18px;font-weight:800}
163
+ h2{font-size:32px;text-align:center}
164
+ .qr-box{background:#fff;padding:22px;border-radius:18px}
165
+ .qr-box img{display:block;width:320px;height:320px}
166
+ .url{font-family:monospace;font-size:16px;background:rgba(0,0,0,0.35);padding:12px 18px;border-radius:8px;word-break:break-all;text-align:center;max-width:100%}
167
+ .note{font-size:20px;text-align:center;line-height:1.5;opacity:0.95}
168
+ .howto{background:rgba(0,0,0,0.3);border-radius:14px;padding:22px;font-size:19px;line-height:1.7;width:100%;max-width:600px}
169
+ .howto h3{font-size:22px;margin-bottom:12px}
170
+ .howto ol{padding-left:28px}
171
+ .howto li{margin:8px 0}
172
+ .warn-soft{background:rgba(241,196,15,0.2);border:1px solid rgba(241,196,15,0.4);padding:18px;border-radius:12px;font-size:17px;line-height:1.5;text-align:center;max-width:600px}
173
+ footer{font-size:14px;opacity:0.7;text-align:center;line-height:1.6;max-width:700px;padding:16px;background:rgba(0,0,0,0.2);border-radius:10px}
174
+ </style></head><body>
175
+ <button class="lang-btn" id="lang">ไทย</button>
176
+ <button class="stop-btn" id="stop" data-en="🛑 STOP" data-th="🛑 หยุด"></button>
177
+ <div class="wrap">
178
+ <h1 data-en="Send brain to phone" data-th="ส่งสมองไปมือถือ"></h1>
179
+ <div class="tagline" data-en="Open your phone camera. Scan the QR. Tap the link. Tap green button." data-th="เปิดกล้องมือถือ → สแกน QR → กดที่ link → กดปุ่มเขียว"></div>
180
+ <div class="primary">
181
+ <span class="pill" data-en="${labelEn}" data-th="${labelTh}"></span>
182
+ <h2 data-en="Scan this QR" data-th="สแกน QR นี้"></h2>
183
+ <div class="qr-box"><img src="${escapeHtml(buildQrUrl(input.primaryUrl, 360))}" alt=""></div>
184
+ <div class="url">${url}</div>
185
+ <div class="note" data-en="${noteEn}" data-th="${noteTh}"></div>
186
+ </div>
187
+ <div class="howto">
188
+ <h3 data-en="📱 What happens after you scan" data-th="📱 หลังสแกน QR จะเกิดอะไรขึ้น"></h3>
189
+ <ol>
190
+ <li data-en="Phone camera shows the URL — tap it." data-th="กล้องมือถือแสดง URL — กดที่ URL"></li>
191
+ <li data-en="Mobile browser opens a page with a green button + capability matrix." data-th="เบราว์เซอร์เปิดหน้าเว็บที่มีปุ่มเขียว + ตารางความสามารถ"></li>
192
+ <li data-en="Tap green → pick AI app from share menu → tap send." data-th="กดปุ่มเขียว → เลือก AI app จาก share menu → กด send"></li>
193
+ <li data-en="If share menu doesn't appear, tap blue COPY → open AI app → paste." data-th="ถ้าไม่มี share menu ขึ้น กด COPY สีฟ้า → เปิด AI app → paste"></li>
194
+ </ol>
195
+ </div>
196
+ <div class="warn-soft">
197
+ <span data-en="⚠ Honest truth: paste gives the AI READ-ONLY memory. For LIVE Mneme tool execution that AI must have Mneme installed (Cursor / Claude Code / Codex / VS Code MCP). Web AIs (chatgpt.com, gemini.com) read but can NOT call MCP. They CAN suggest next actions back via HOMUNCULUS RETURN block — paste it back to your editor AI to execute." data-th="⚠ ความจริง: paste ให้ AI เห็น MEMORY แบบอ่านอย่างเดียว. ถ้าจะให้ AI เรียก Mneme tools จริง AI ตัวนั้นต้องติดตั้ง Mneme (Cursor / Claude Code / Codex / VS Code MCP). Web AIs อ่านได้แต่เรียก MCP ไม่ได้. แต่มัน suggest next actions กลับมาเป็น HOMUNCULUS RETURN block ได้ — paste กลับไป editor AI เพื่อ execute"></span>
198
+ </div>
199
+ <footer>
200
+ <span data-en="Soul ${input.soulTokens} tokens · ${tunnelMention}LAN :7741${pasteMention}" data-th="สมอง ${input.soulTokens} โทเค็น · ${tunnelMention}LAN :7741${pasteMention}"></span><br>
201
+ <span data-en="Done? Click the red STOP button at top-right." data-th="เสร็จแล้ว? กดปุ่ม STOP สีแดงมุมขวาบน"></span>
202
+ </footer>
203
+ </div>
204
+ <script>
205
+ let lang = ${JSON.stringify(lang)};
206
+ function applyLang() {
207
+ document.querySelectorAll("[data-en]").forEach(el => { el.textContent = el.dataset[lang] || el.dataset.en; });
208
+ document.getElementById("lang").textContent = lang === "en" ? "ไทย" : "EN";
209
+ document.documentElement.lang = lang;
210
+ }
211
+ applyLang();
212
+ document.getElementById("lang").onclick = () => { lang = lang === "en" ? "th" : "en"; applyLang(); };
213
+ document.getElementById("stop").onclick = async () => {
214
+ if (!confirm(lang === "th" ? "หยุด server? หน้านี้จะใช้ไม่ได้แล้ว" : "Stop the server? This page will stop working.")) return;
215
+ try { await fetch(${jsSafe(input.primaryUrl)} + "/stop"); } catch (e) {}
216
+ document.body.innerHTML = '<div style="padding:60px;text-align:center;font-size:24px;color:#fff;background:#16a085;min-height:100vh">' + (lang === "th" ? "✓ Server หยุดแล้ว ปิด tab นี้ได้" : "✓ Server stopped. You can close this tab.") + '</div>';
217
+ };
218
+ </script>
219
+ </body></html>`;
220
+ }
221
+ //# sourceMappingURL=page_renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page_renderer.js","sourceRoot":"","sources":["../../src/rainbow/page_renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAuBH,SAAS,MAAM,CAAC,CAAS;IACvB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC;SACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,UAAU,CAAC,OAAe,EAAE,IAAI,GAAG,GAAG;IAC7C,OAAO,oDAAoD,IAAI,IAAI,IAAI,8BAA8B,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;AACrI,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAsB;IACrD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC;IACvC,OAAO,8BAA8B,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eA6D5B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;aACxB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAsCT,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAkB;IAC7C,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC;IACvC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/D,OAAO,8BAA8B,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAiCX,OAAO,cAAc,OAAO;;kCAE1B,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;qBAC1D,GAAG;+BACO,MAAM,cAAc,MAAM;;;;;;;;;;;;;;;wBAejC,KAAK,CAAC,UAAU,aAAa,aAAa,YAAY,YAAY,mBAAmB,KAAK,CAAC,UAAU,aAAa,aAAa,YAAY,YAAY;;;;;aAKlK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;;;;;;;;;;sBAUX,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;;;;eAI/B,CAAC;AAChB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=v1_91.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v1_91.test.d.ts","sourceRoot":"","sources":["../../src/rainbow/v1_91.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,111 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { renderMobilePage, renderPcPage } from "./page_renderer.js";
3
+ describe("v1.91 RAINBOW · mobile page renderer", () => {
4
+ it("emits a complete HTML document", () => {
5
+ const html = renderMobilePage({ soulText: "# SOUL\nbody" });
6
+ expect(html.startsWith("<!doctype html>")).toBe(true);
7
+ expect(html).toContain("</html>");
8
+ expect(html).toContain("Mneme handoff");
9
+ });
10
+ it("includes Web Share API + clipboard + textarea fallback chain", () => {
11
+ const html = renderMobilePage({ soulText: "x" });
12
+ expect(html).toContain("navigator.share");
13
+ expect(html).toContain("navigator.clipboard");
14
+ expect(html).toContain("execCommand");
15
+ });
16
+ it("XSS-safe: closing </script> in soul is escaped", () => {
17
+ const html = renderMobilePage({ soulText: 'evil </script><img onerror=alert(1)>' });
18
+ expect(html).toContain("<\\/script>");
19
+ // Original (raw) </script> token must NOT appear in the JS string section
20
+ const scriptStart = html.indexOf("const SOUL = ");
21
+ const scriptEnd = html.indexOf(";", scriptStart);
22
+ const soulLiteral = html.slice(scriptStart, scriptEnd);
23
+ expect(soulLiteral).not.toContain("</script>");
24
+ });
25
+ it("ships bilingual data-en/data-th attributes for UI strings", () => {
26
+ const html = renderMobilePage({ soulText: "x" });
27
+ expect(html).toContain('data-en="Mneme handoff"');
28
+ expect(html).toContain('data-th="ส่งสมอง Mneme"');
29
+ });
30
+ it("includes the honest capability matrix (paste vs MCP truth)", () => {
31
+ const html = renderMobilePage({ soulText: "x" });
32
+ expect(html).toContain("Read this conversation");
33
+ expect(html).toContain("Call Mneme MCP tools");
34
+ expect(html).toContain("HOMUNCULUS RETURN block");
35
+ });
36
+ it("includes 4-vendor quick links (ChatGPT/Gemini/Claude/Perplexity)", () => {
37
+ const html = renderMobilePage({ soulText: "x" });
38
+ expect(html).toContain("chatgpt.com");
39
+ expect(html).toContain("gemini.google.com");
40
+ expect(html).toContain("claude.ai");
41
+ expect(html).toContain("perplexity.ai");
42
+ });
43
+ it("respects defaultLang option", () => {
44
+ const en = renderMobilePage({ soulText: "x", defaultLang: "en" });
45
+ const th = renderMobilePage({ soulText: "x", defaultLang: "th" });
46
+ expect(en).toContain('let lang = "en"');
47
+ expect(th).toContain('let lang = "th"');
48
+ });
49
+ });
50
+ describe("v1.91 RAINBOW · PC page renderer", () => {
51
+ const baseInput = {
52
+ primaryUrl: "http://192.168.1.10:7741",
53
+ label: { en: "Same Wi-Fi · 1 tap", th: "WiFi เดียวกัน · 1 แตะ" },
54
+ note: { en: "Phone MUST be on the same WiFi", th: "มือถือต้องอยู่ WiFi เดียวกับ PC" },
55
+ soulTokens: 1234,
56
+ hasTunnel: false,
57
+ hasPaste: true,
58
+ };
59
+ it("emits a complete HTML page", () => {
60
+ const html = renderPcPage(baseInput);
61
+ expect(html.startsWith("<!doctype html>")).toBe(true);
62
+ expect(html).toContain("</html>");
63
+ expect(html).toContain("Send brain to phone");
64
+ });
65
+ it("renders ONE primary QR pointing at the QR rendering service", () => {
66
+ const html = renderPcPage(baseInput);
67
+ expect(html).toContain("api.qrserver.com");
68
+ expect(html).toContain(encodeURIComponent("http://192.168.1.10:7741"));
69
+ });
70
+ it("includes STOP button (no Ctrl+C jargon)", () => {
71
+ const html = renderPcPage(baseInput);
72
+ expect(html).toContain("🛑 STOP");
73
+ expect(html).toContain('id="stop"');
74
+ expect(html).not.toContain("Ctrl+C in the terminal");
75
+ expect(html).not.toContain("Press Ctrl+C");
76
+ });
77
+ it("STOP button confirms before stopping (in selected language)", () => {
78
+ const html = renderPcPage(baseInput);
79
+ expect(html).toContain("confirm(");
80
+ expect(html).toContain("Server stopped");
81
+ expect(html).toContain("Server หยุดแล้ว");
82
+ });
83
+ it("footer reflects tunnel + paste availability", () => {
84
+ const noTunnel = renderPcPage({ ...baseInput, hasTunnel: false, hasPaste: false });
85
+ expect(noTunnel).not.toContain("Cloudflare tunnel");
86
+ const withTunnel = renderPcPage({ ...baseInput, hasTunnel: true, hasPaste: true });
87
+ expect(withTunnel).toContain("Cloudflare tunnel");
88
+ expect(withTunnel).toContain("paste fallback");
89
+ });
90
+ it("escapes HTML in label/note (XSS-safe)", () => {
91
+ const evil = {
92
+ ...baseInput,
93
+ label: { en: '<script>alert(1)</script>', th: 'ก' },
94
+ note: { en: 'a"b', th: 'b' },
95
+ };
96
+ const html = renderPcPage(evil);
97
+ expect(html).not.toContain("<script>alert(1)</script>");
98
+ expect(html).toContain("&lt;script&gt;alert(1)&lt;/script&gt;");
99
+ });
100
+ it("primary URL appears as displayed text + inside the QR encoder URL", () => {
101
+ const html = renderPcPage({ ...baseInput, primaryUrl: "https://abc.trycloudflare.com" });
102
+ expect(html).toContain("https://abc.trycloudflare.com");
103
+ expect(html).toContain(encodeURIComponent("https://abc.trycloudflare.com"));
104
+ });
105
+ it("STOP fetch URL is the primaryUrl + /stop, JSON-encoded for safety", () => {
106
+ const html = renderPcPage({ ...baseInput, primaryUrl: 'http://x.com/"</script>' });
107
+ // </script> in fetch arg must be escaped
108
+ expect(html).toContain("<\\/script>");
109
+ });
110
+ });
111
+ //# sourceMappingURL=v1_91.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v1_91.test.js","sourceRoot":"","sources":["../../src/rainbow/v1_91.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEpE,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,QAAQ,EAAE,sCAAsC,EAAE,CAAC,CAAC;QACpF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACtC,0EAA0E;QAC1E,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACjD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACvD,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,EAAE,GAAG,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,MAAM,EAAE,GAAG,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QACxC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAChD,MAAM,SAAS,GAAG;QAChB,UAAU,EAAE,0BAA0B;QACtC,KAAK,EAAE,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAE,uBAAuB,EAAE;QAChE,IAAI,EAAE,EAAE,EAAE,EAAE,gCAAgC,EAAE,EAAE,EAAE,iCAAiC,EAAE;QACrF,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC;IAEF,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,GAAG,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACnF,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,YAAY,CAAC,EAAE,GAAG,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACnF,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAClD,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,IAAI,GAAG;YACX,GAAG,SAAS;YACZ,KAAK,EAAE,EAAE,EAAE,EAAE,2BAA2B,EAAE,EAAE,EAAE,GAAG,EAAE;YACnD,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE;SAC7B,CAAC;QACF,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,uCAAuC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,GAAG,SAAS,EAAE,UAAU,EAAE,+BAA+B,EAAE,CAAC,CAAC;QACzF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,+BAA+B,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,GAAG,SAAS,EAAE,UAAU,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACnF,yCAAyC;QACzC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
- {
1
+ {
2
2
  "name": "@mneme-ai/core",
3
- "version": "1.90.0",
3
+ "version": "1.91.0",
4
4
  "description": "Core indexing, retrieval, and graph engine for Mneme",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",