@mneme-ai/core 1.97.0 → 1.99.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 (66) hide show
  1. package/dist/flash/devils_advocate.d.ts +66 -0
  2. package/dist/flash/devils_advocate.d.ts.map +1 -0
  3. package/dist/flash/devils_advocate.js +154 -0
  4. package/dist/flash/devils_advocate.js.map +1 -0
  5. package/dist/flash/flash.d.ts +50 -0
  6. package/dist/flash/flash.d.ts.map +1 -0
  7. package/dist/flash/flash.js +67 -0
  8. package/dist/flash/flash.js.map +1 -0
  9. package/dist/flash/flash.test.d.ts +2 -0
  10. package/dist/flash/flash.test.d.ts.map +1 -0
  11. package/dist/flash/flash.test.js +221 -0
  12. package/dist/flash/flash.test.js.map +1 -0
  13. package/dist/flash/grounding.d.ts +55 -0
  14. package/dist/flash/grounding.d.ts.map +1 -0
  15. package/dist/flash/grounding.js +144 -0
  16. package/dist/flash/grounding.js.map +1 -0
  17. package/dist/flash/index.d.ts +18 -0
  18. package/dist/flash/index.d.ts.map +1 -0
  19. package/dist/flash/index.js +18 -0
  20. package/dist/flash/index.js.map +1 -0
  21. package/dist/flash/predictive.d.ts +44 -0
  22. package/dist/flash/predictive.d.ts.map +1 -0
  23. package/dist/flash/predictive.js +76 -0
  24. package/dist/flash/predictive.js.map +1 -0
  25. package/dist/flash/veracity.d.ts +99 -0
  26. package/dist/flash/veracity.d.ts.map +1 -0
  27. package/dist/flash/veracity.js +107 -0
  28. package/dist/flash/veracity.js.map +1 -0
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +7 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/permeate/userscript_generator.d.ts.map +1 -1
  34. package/dist/permeate/userscript_generator.js +1 -0
  35. package/dist/permeate/userscript_generator.js.map +1 -1
  36. package/dist/rainbow/index.d.ts +3 -0
  37. package/dist/rainbow/index.d.ts.map +1 -1
  38. package/dist/rainbow/index.js +11 -0
  39. package/dist/rainbow/index.js.map +1 -1
  40. package/dist/rainbow/passport.d.ts +130 -0
  41. package/dist/rainbow/passport.d.ts.map +1 -0
  42. package/dist/rainbow/passport.js +180 -0
  43. package/dist/rainbow/passport.js.map +1 -0
  44. package/dist/rainbow/passport_v99.test.d.ts +2 -0
  45. package/dist/rainbow/passport_v99.test.d.ts.map +1 -0
  46. package/dist/rainbow/passport_v99.test.js +53 -0
  47. package/dist/rainbow/passport_v99.test.js.map +1 -0
  48. package/dist/rainbow/v1_98.test.d.ts +2 -0
  49. package/dist/rainbow/v1_98.test.d.ts.map +1 -0
  50. package/dist/rainbow/v1_98.test.js +307 -0
  51. package/dist/rainbow/v1_98.test.js.map +1 -0
  52. package/dist/rainbow/vendor_probe.d.ts +52 -0
  53. package/dist/rainbow/vendor_probe.d.ts.map +1 -0
  54. package/dist/rainbow/vendor_probe.js +111 -0
  55. package/dist/rainbow/vendor_probe.js.map +1 -0
  56. package/dist/rainbow/vendor_strategy.d.ts +64 -0
  57. package/dist/rainbow/vendor_strategy.d.ts.map +1 -0
  58. package/dist/rainbow/vendor_strategy.js +157 -0
  59. package/dist/rainbow/vendor_strategy.js.map +1 -0
  60. package/dist/relay/deep_link.d.ts +24 -15
  61. package/dist/relay/deep_link.d.ts.map +1 -1
  62. package/dist/relay/deep_link.js +28 -18
  63. package/dist/relay/deep_link.js.map +1 -1
  64. package/dist/v1_87_regression.test.js +3 -2
  65. package/dist/v1_87_regression.test.js.map +1 -1
  66. package/package.json +1 -1
@@ -0,0 +1,307 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import {
3
+ // vendor_strategy
4
+ VENDOR_REGISTRY, entryOf, pickStrategy, formatStrategyPulseLine,
5
+ // vendor_probe
6
+ probeAllVendors, failingProbes, formatProbePulseLine,
7
+ // passport
8
+ issuePassport, verifyPassport, serializePassport, parsePassport, generatePassportSecret, fingerprintEntries, estimatePassportTokens, formatPassportPulseLine, } from "./index.js";
9
+ import { composeCleanPrompt, buildDeepLink } from "../relay/deep_link.js";
10
+ // ============================ STALE-URL FIX ============================
11
+ describe("v1.98 · stale-URL fix (chat.openai.com → chatgpt.com)", () => {
12
+ it("buildDeepLink('chatgpt') uses chatgpt.com (NOT chat.openai.com)", () => {
13
+ const dl = buildDeepLink({ pasteUrl: "https://x", nexusCode: "ABC", vendor: "chatgpt" });
14
+ expect(dl.url).toMatch(/^https:\/\/chatgpt\.com\/\?q=/);
15
+ expect(dl.url).not.toContain("chat.openai.com");
16
+ });
17
+ it("composeCleanPrompt replaces fetch+decrypt instruction (v1.98 clean form)", () => {
18
+ const p = composeCleanPrompt();
19
+ expect(p).toContain("Mneme soul prompt");
20
+ // The clean prompt MUST NOT instruct AI to fetch/decrypt
21
+ expect(p.toLowerCase()).not.toContain("fetch");
22
+ expect(p.toLowerCase()).not.toContain("decrypt");
23
+ expect(p.toLowerCase()).not.toContain("aes");
24
+ });
25
+ });
26
+ // ============================ VENDOR STRATEGY ============================
27
+ describe("v1.98 · vendor strategy map", () => {
28
+ it("registry has 10+ vendor entries", () => {
29
+ expect(VENDOR_REGISTRY.length).toBeGreaterThanOrEqual(10);
30
+ });
31
+ it("ChatGPT-web: free=clipboard-first, qParamWorks=false (verified)", () => {
32
+ const e = entryOf("chatgpt-web");
33
+ expect(e.freeStrategy).toBe("clipboard-first");
34
+ expect(e.qParamWorks).toBe(false);
35
+ expect(e.webFetchAvailable).toBe(false);
36
+ expect(e.homeUrl).toBe("https://chatgpt.com/");
37
+ });
38
+ it("Gemini-web: clipboard-first on both tiers (q= prefill verified unreliable)", () => {
39
+ const e = entryOf("gemini-web");
40
+ expect(e.freeStrategy).toBe("clipboard-first");
41
+ expect(e.paidStrategy).toBe("clipboard-first");
42
+ expect(e.qParamWorks).toBe(false);
43
+ });
44
+ it("Claude Code / Cursor: mcp-direct strategy", () => {
45
+ expect(entryOf("claude-code")?.freeStrategy).toBe("mcp-direct");
46
+ expect(entryOf("cursor")?.freeStrategy).toBe("mcp-direct");
47
+ });
48
+ it("Perplexity: clipboard-first by default, prefill-and-paste opt-in via paidStrategy", () => {
49
+ const e = entryOf("perplexity-web");
50
+ expect(e.freeStrategy).toBe("clipboard-first");
51
+ expect(e.qParamWorks).toBe(true); // Perplexity does honor ?q=
52
+ });
53
+ it("mobile-app vendors: app-deeplink-NA (no URL scheme exists)", () => {
54
+ expect(entryOf("gemini-mobile")?.freeStrategy).toBe("app-deeplink-NA");
55
+ expect(entryOf("chatgpt-mobile")?.freeStrategy).toBe("app-deeplink-NA");
56
+ });
57
+ it("any-mobile-browser: plain-qr (no encryption, no fetch instruction)", () => {
58
+ expect(entryOf("any-mobile-browser")?.freeStrategy).toBe("plain-qr");
59
+ });
60
+ it("pickStrategy returns the strategy + reason", () => {
61
+ const r = pickStrategy("chatgpt-web", { paidTier: false });
62
+ expect(r.strategy).toBe("clipboard-first");
63
+ expect(r.reason).toContain("chatgpt-web");
64
+ });
65
+ it("pickStrategy on unknown vendor → defaults to clipboard-first", () => {
66
+ const r = pickStrategy("xyz-unknown");
67
+ expect(r.strategy).toBe("clipboard-first");
68
+ expect(r.entry).toBeNull();
69
+ });
70
+ it("every entry has lastChecked date in ISO format", () => {
71
+ for (const e of VENDOR_REGISTRY) {
72
+ expect(e.lastChecked).toMatch(/^\d{4}-\d{2}-\d{2}$/);
73
+ }
74
+ });
75
+ it("formatStrategyPulseLine produces compact summary", () => {
76
+ const line = formatStrategyPulseLine("chatgpt-web");
77
+ expect(line).toContain("VENDOR-STRATEGY");
78
+ expect(line).toContain("clipboard-first");
79
+ });
80
+ });
81
+ // ============================ VENDOR PROBE ============================
82
+ describe("v1.98 · vendor URL probe", () => {
83
+ function mockFetch(responses) {
84
+ return (async (url) => {
85
+ const u = typeof url === "string" ? url : url.toString();
86
+ const r = responses[u];
87
+ if (!r)
88
+ throw new Error(`mock fetch: no response for ${u}`);
89
+ // Vitest's Response uses globalThis.Response; .url is read-only normally.
90
+ const res = new Response("", { status: r.status });
91
+ // Spoof res.url via prototype override
92
+ Object.defineProperty(res, "url", { value: r.finalUrl ?? u, configurable: true });
93
+ return res;
94
+ });
95
+ }
96
+ it("OK verdict when status 200 and host unchanged", async () => {
97
+ const fetchImpl = mockFetch({
98
+ "https://chatgpt.com/": { status: 200 },
99
+ "https://gemini.google.com/app": { status: 200 },
100
+ "https://claude.ai/new": { status: 200 },
101
+ "https://github.com/copilot": { status: 200 },
102
+ "https://www.perplexity.ai/": { status: 200 },
103
+ });
104
+ const results = await probeAllVendors({ fetchImpl });
105
+ const chatgpt = results.find((r) => r.vendor === "chatgpt-web");
106
+ expect(chatgpt.verdict).toBe("OK");
107
+ expect(chatgpt.hostChanged).toBe(false);
108
+ });
109
+ it("REDIRECT_HOST_CHANGE verdict catches stale URLs (chat.openai.com → chatgpt.com)", async () => {
110
+ // Inject a vendor entry with a stale URL to demonstrate the catch.
111
+ const fetchImpl = (async (url) => {
112
+ const r = new Response("", { status: 200 });
113
+ Object.defineProperty(r, "url", { value: "https://chatgpt.com/", configurable: true });
114
+ return r;
115
+ });
116
+ // Manually probe a stale URL via the same logic
117
+ const { probeAllVendors: probe } = await import("./vendor_probe.js");
118
+ // We can't directly inject a stale URL without modifying registry, so
119
+ // we test the host-changed detector via formatProbePulseLine:
120
+ const fakeResults = [
121
+ { vendor: "chatgpt-web-stale", url: "https://chat.openai.com/", finalUrl: "https://chatgpt.com/", status: 200, hostChanged: true, verdict: "REDIRECT_HOST_CHANGE", notes: "redirected from chat.openai.com to chatgpt.com — update vendor_strategy.ts homeUrl", elapsedMs: 5 },
122
+ { vendor: "gemini-web", url: "https://gemini.google.com/app", finalUrl: "https://gemini.google.com/app", status: 200, hostChanged: false, verdict: "OK", notes: "reachable (status 200)", elapsedMs: 5 },
123
+ ];
124
+ expect(failingProbes(fakeResults).length).toBe(1);
125
+ expect(failingProbes(fakeResults)[0].verdict).toBe("REDIRECT_HOST_CHANGE");
126
+ expect(formatProbePulseLine(fakeResults)).toContain("FAILING");
127
+ void probe;
128
+ });
129
+ it("SKIP verdict for non-HTTP URLs (app schemes)", async () => {
130
+ const fetchImpl = mockFetch({});
131
+ const results = await probeAllVendors({ fetchImpl });
132
+ const skipped = results.filter((r) => r.verdict === "SKIP");
133
+ // gemini-mobile, chatgpt-mobile, any-mobile-browser, claude-code, cursor are not HTTP
134
+ expect(skipped.length).toBeGreaterThanOrEqual(2);
135
+ });
136
+ it("BLOCKED verdict on 403 (Cloudflare)", async () => {
137
+ const fetchImpl = mockFetch({
138
+ "https://chatgpt.com/": { status: 200 },
139
+ "https://gemini.google.com/app": { status: 200 },
140
+ "https://claude.ai/new": { status: 403 },
141
+ "https://github.com/copilot": { status: 200 },
142
+ "https://www.perplexity.ai/": { status: 200 },
143
+ });
144
+ const results = await probeAllVendors({ fetchImpl });
145
+ const claude = results.find((r) => r.vendor === "claude-web");
146
+ expect(claude.verdict).toBe("BLOCKED");
147
+ });
148
+ it("failingProbes ignores OK + SKIP + BLOCKED, surfaces real failures", () => {
149
+ const sample = [
150
+ { vendor: "a", url: "https://a", finalUrl: "https://a", status: 200, hostChanged: false, verdict: "OK", notes: "", elapsedMs: 1 },
151
+ { vendor: "b", url: "https://b", finalUrl: "https://x", status: 200, hostChanged: true, verdict: "REDIRECT_HOST_CHANGE", notes: "", elapsedMs: 1 },
152
+ { vendor: "c", url: "https://c", finalUrl: null, status: 404, hostChanged: false, verdict: "NOT_FOUND", notes: "", elapsedMs: 1 },
153
+ { vendor: "d", url: "https://d", finalUrl: null, status: 403, hostChanged: false, verdict: "BLOCKED", notes: "", elapsedMs: 1 },
154
+ { vendor: "e", url: "claude://", finalUrl: null, status: null, hostChanged: false, verdict: "SKIP", notes: "", elapsedMs: 0 },
155
+ ];
156
+ const fail = failingProbes(sample);
157
+ expect(fail.map((f) => f.vendor)).toEqual(["b", "c"]);
158
+ });
159
+ });
160
+ // ============================ MNEME PASSPORT (disruption) ============================
161
+ describe("v1.98 · MNEME PASSPORT — portable HMAC-signed identity", () => {
162
+ // Fresh copy per test — the TAMPERED test mutates entries and we don't
163
+ // want that to leak into later tests.
164
+ function freshEntries() {
165
+ return [
166
+ { id: "d1", ts: Date.now() - 1000, kind: "decision", text: "Use Postgres native JSONB for v1", scope: "auth-service" },
167
+ { id: "r1", ts: Date.now() - 2000, kind: "regret", text: "JWT 5-min tolerance broke prod 2024-DST", scope: "commit a3f9b21" },
168
+ { id: "w1", ts: Date.now() - 3000, kind: "wisdom", text: "Always cite commits when AI suggests a fix" },
169
+ ];
170
+ }
171
+ const entries = freshEntries(); // legacy reads in tests below — will be reassigned via splice in TAMPERED test
172
+ it("generatePassportSecret produces 32 bytes", () => {
173
+ const s = generatePassportSecret();
174
+ expect(s.length).toBe(32);
175
+ });
176
+ it("issuePassport produces a valid envelope (signed)", () => {
177
+ const secret = generatePassportSecret();
178
+ const env = issuePassport({ holder: "alice@mneme", entries, secret });
179
+ expect(env.holder).toBe("alice@mneme");
180
+ expect(env.alg).toBe("HMAC-SHA256");
181
+ expect(env.signature.length).toBe(64); // 32 bytes hex = 64 chars
182
+ expect(env.entries.length).toBe(3);
183
+ expect(env.entriesHash.length).toBeGreaterThan(0);
184
+ });
185
+ it("verifyPassport returns VALID for unmodified envelope + correct secret", () => {
186
+ const secret = generatePassportSecret();
187
+ const env = issuePassport({ holder: "alice", entries, secret });
188
+ const r = verifyPassport(env, secret);
189
+ expect(r.verdict).toBe("VALID");
190
+ expect(r.ok).toBe(true);
191
+ });
192
+ it("verifyPassport returns TAMPERED when entries modified", () => {
193
+ const secret = generatePassportSecret();
194
+ const env = issuePassport({ holder: "alice", entries, secret });
195
+ // Mutate an entry
196
+ env.entries[0].text = "MODIFIED EVIL DECISION";
197
+ const r = verifyPassport(env, secret);
198
+ expect(r.verdict).toBe("TAMPERED");
199
+ expect(r.ok).toBe(false);
200
+ });
201
+ it("verifyPassport returns TAMPERED when signature is forged", () => {
202
+ const secret = generatePassportSecret();
203
+ const env = issuePassport({ holder: "alice", entries, secret });
204
+ env.signature = "0".repeat(64);
205
+ const r = verifyPassport(env, secret);
206
+ expect(r.verdict).toBe("TAMPERED");
207
+ });
208
+ it("verifyPassport returns WRONG_KEY when secret doesn't match", () => {
209
+ const secret1 = generatePassportSecret();
210
+ const secret2 = generatePassportSecret();
211
+ const env = issuePassport({ holder: "alice", entries, secret: secret1 });
212
+ const r = verifyPassport(env, secret2);
213
+ expect(r.verdict).toBe("WRONG_KEY");
214
+ });
215
+ it("verifyPassport returns EXPIRED when past TTL", () => {
216
+ const secret = generatePassportSecret();
217
+ const env = issuePassport({ holder: "alice", entries, secret, ttlDays: 0 });
218
+ // Force expiry into the past
219
+ env.expiresAt = Date.now() - 1000;
220
+ const r = verifyPassport(env, secret);
221
+ expect(r.verdict).toBe("EXPIRED");
222
+ });
223
+ it("serialize → parse round-trips", () => {
224
+ const secret = generatePassportSecret();
225
+ const env = issuePassport({ holder: "alice", entries, secret });
226
+ const text = serializePassport(env);
227
+ expect(text).toContain("MNEME PASSPORT v1");
228
+ expect(text).toContain("--- BEGIN JSON ---");
229
+ const parsed = parsePassport(text);
230
+ expect(parsed).not.toBeNull();
231
+ expect(parsed?.signature).toBe(env.signature);
232
+ expect(parsed?.entries.length).toBe(3);
233
+ // Verify after round-trip
234
+ expect(verifyPassport(parsed, secret).ok).toBe(true);
235
+ });
236
+ it("parsePassport returns null on malformed input", () => {
237
+ expect(parsePassport("not a passport")).toBeNull();
238
+ expect(parsePassport("--- BEGIN JSON --- {bad json}")).toBeNull();
239
+ });
240
+ it("issuePassport caps entries to maxEntries (newest first)", () => {
241
+ const secret = generatePassportSecret();
242
+ const many = [];
243
+ for (let i = 0; i < 100; i++)
244
+ many.push({ id: `e${i}`, ts: i, kind: "decision", text: `decision ${i}` });
245
+ const env = issuePassport({ holder: "alice", entries: many, secret, maxEntries: 10 });
246
+ expect(env.entries.length).toBe(10);
247
+ // Newest first → highest ts → entries 90..99
248
+ expect(env.entries[0].id).toBe("e99");
249
+ expect(env.entries[9].id).toBe("e90");
250
+ });
251
+ it("fingerprintEntries is deterministic + sensitive to changes", () => {
252
+ const a = fingerprintEntries(entries);
253
+ const b = fingerprintEntries(entries);
254
+ expect(a).toBe(b);
255
+ const modified = [...entries, { id: "x", ts: 1, kind: "wisdom", text: "extra" }];
256
+ expect(fingerprintEntries(modified)).not.toBe(a);
257
+ });
258
+ it("estimatePassportTokens returns a positive number", () => {
259
+ const secret = generatePassportSecret();
260
+ const env = issuePassport({ holder: "alice", entries, secret });
261
+ expect(estimatePassportTokens(env)).toBeGreaterThan(0);
262
+ // Typical passport with 3 entries should fit in ~500 tokens
263
+ expect(estimatePassportTokens(env)).toBeLessThan(800);
264
+ });
265
+ it("formatPassportPulseLine produces compact summary", () => {
266
+ const secret = generatePassportSecret();
267
+ const env = issuePassport({ holder: "alice", entries, secret });
268
+ const line = formatPassportPulseLine(env);
269
+ expect(line).toContain("MNEME-PASSPORT");
270
+ expect(line).toContain("alice");
271
+ expect(line).toContain("entries=3");
272
+ });
273
+ it("the disruption: any AI can READ entries without secret (only VERIFY needs secret)", () => {
274
+ const secret = generatePassportSecret();
275
+ const env = issuePassport({ holder: "alice", entries: freshEntries(), secret });
276
+ const text = serializePassport(env);
277
+ const parsed = parsePassport(text);
278
+ // ANY AI agent — without the secret — can still see the entries
279
+ expect(parsed.entries.map((e) => e.text)).toContain("Use Postgres native JSONB for v1");
280
+ expect(parsed.entries.map((e) => e.text)).toContain("Always cite commits when AI suggests a fix");
281
+ // But cannot forge a new envelope without the secret
282
+ const wrongSecret = generatePassportSecret();
283
+ expect(verifyPassport(parsed, wrongSecret).verdict).toBe("WRONG_KEY");
284
+ });
285
+ });
286
+ // ============================ ADDITIONAL FLEXIBLE-PHRASE COVERAGE ============================
287
+ describe("v1.98 · flexible phrase recognition (user complained about pattern memorization)", () => {
288
+ // Each phrase from real Thai/English conversational forms — confirms parser
289
+ // doesn't require exact wording. Imported lazily so we don't break the file
290
+ // structure when this module evolves.
291
+ it("loose phrasings without exact 'mneme' word still trigger", async () => {
292
+ const { parseCloneIntent } = await import("./clone_to.js");
293
+ const phrases = [
294
+ "ผมอยากจะส่งบริบทไปที่ samsung", // unusual verb form + samsung
295
+ "Help me put context on iPhone", // English "put"
296
+ "เอา mneme ลงโทรศัพท์ที", // "เอา ลง" verb form
297
+ "อยากให้ brain ไปอยู่ใน ipad", // "อยากให้ ไปอยู่"
298
+ "save my brain to gemini please", // "save"
299
+ ];
300
+ for (const p of phrases) {
301
+ const r = parseCloneIntent(p);
302
+ expect(r.target).not.toBe("unknown");
303
+ expect(r.isCloneRequest).toBe(true);
304
+ }
305
+ });
306
+ });
307
+ //# sourceMappingURL=v1_98.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v1_98.test.js","sourceRoot":"","sources":["../../src/rainbow/v1_98.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * v1.98.0 -- RAINBOW · Vendor URL probe.
3
+ *
4
+ * Closes the "comment lies" gap that v1.85-1.96 had: code comments
5
+ * claimed "Verified May 2026" but no test actually hit the vendor URL.
6
+ * The user found that `chat.openai.com` had been replaced by
7
+ * `chatgpt.com` more than a year prior and our code was still pointing
8
+ * at the dead host.
9
+ *
10
+ * This module does the simplest thing that catches stale URLs: HEAD
11
+ * each vendor home URL, record the response status + final URL after
12
+ * redirects + whether the host changed. If the host changes (e.g.
13
+ * chat.openai.com → chatgpt.com via 308), we flag it loudly.
14
+ *
15
+ * NOT a Playwright integration test — those need browser binaries +
16
+ * are flaky in CI. This is a deterministic, fast (one HEAD per
17
+ * vendor), zero-dependency check that the URL is at least reachable
18
+ * and not silently redirected to a different host.
19
+ *
20
+ * Run via:
21
+ * - Manually: `node -e "import('./vendor_probe.js').then(m => m.probeAllVendors().then(console.log))"`
22
+ * - In CI: daemon's nightly cycle (future) — surfaces stale URLs as inbox warnings
23
+ * - Test: `vendor_probe.test.ts` mocks fetch + asserts the redirect-detection logic
24
+ */
25
+ export interface ProbeResult {
26
+ vendor: string;
27
+ url: string;
28
+ finalUrl: string | null;
29
+ status: number | null;
30
+ hostChanged: boolean;
31
+ /** Verdict: OK / REDIRECT_HOST_CHANGE / 404 / NETWORK_ERR / SKIP. */
32
+ verdict: "OK" | "REDIRECT_HOST_CHANGE" | "NOT_FOUND" | "NETWORK_ERR" | "BLOCKED" | "SKIP";
33
+ /** Notes for human / AI agent. */
34
+ notes: string;
35
+ elapsedMs: number;
36
+ }
37
+ export interface ProbeOptions {
38
+ /** Override fetch (for tests). */
39
+ fetchImpl?: typeof fetch;
40
+ /** Max time per probe in ms. Default 8000. */
41
+ timeoutMs?: number;
42
+ /** User-Agent header. */
43
+ userAgent?: string;
44
+ }
45
+ /** Probe every registered vendor concurrently. Returns one ProbeResult
46
+ * per vendor. Total elapsed time ≈ slowest probe. */
47
+ export declare function probeAllVendors(opts?: ProbeOptions): Promise<ProbeResult[]>;
48
+ /** Probe results that should ALERT — anything that isn't OK or SKIP. */
49
+ export declare function failingProbes(results: ProbeResult[]): ProbeResult[];
50
+ /** One-line summary suitable for the pulse / CI logs. */
51
+ export declare function formatProbePulseLine(results: ProbeResult[]): string;
52
+ //# sourceMappingURL=vendor_probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor_probe.d.ts","sourceRoot":"","sources":["../../src/rainbow/vendor_probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,qEAAqE;IACrE,OAAO,EAAE,IAAI,GAAG,sBAAsB,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,MAAM,CAAC;IAC1F,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8DD;sDACsD;AACtD,wBAAsB,eAAe,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAErF;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAEnE;AAED,yDAAyD;AACzD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAMnE"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * v1.98.0 -- RAINBOW · Vendor URL probe.
3
+ *
4
+ * Closes the "comment lies" gap that v1.85-1.96 had: code comments
5
+ * claimed "Verified May 2026" but no test actually hit the vendor URL.
6
+ * The user found that `chat.openai.com` had been replaced by
7
+ * `chatgpt.com` more than a year prior and our code was still pointing
8
+ * at the dead host.
9
+ *
10
+ * This module does the simplest thing that catches stale URLs: HEAD
11
+ * each vendor home URL, record the response status + final URL after
12
+ * redirects + whether the host changed. If the host changes (e.g.
13
+ * chat.openai.com → chatgpt.com via 308), we flag it loudly.
14
+ *
15
+ * NOT a Playwright integration test — those need browser binaries +
16
+ * are flaky in CI. This is a deterministic, fast (one HEAD per
17
+ * vendor), zero-dependency check that the URL is at least reachable
18
+ * and not silently redirected to a different host.
19
+ *
20
+ * Run via:
21
+ * - Manually: `node -e "import('./vendor_probe.js').then(m => m.probeAllVendors().then(console.log))"`
22
+ * - In CI: daemon's nightly cycle (future) — surfaces stale URLs as inbox warnings
23
+ * - Test: `vendor_probe.test.ts` mocks fetch + asserts the redirect-detection logic
24
+ */
25
+ import { VENDOR_REGISTRY } from "./vendor_strategy.js";
26
+ function hostOf(url) {
27
+ try {
28
+ return new URL(url).host;
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ async function probeOne(entry, opts = {}) {
35
+ const url = entry.homeUrl;
36
+ if (!url || !url.startsWith("http")) {
37
+ return {
38
+ vendor: entry.id, url, finalUrl: null, status: null, hostChanged: false,
39
+ verdict: "SKIP", notes: `non-HTTP url (probably an app deep-link scheme)`, elapsedMs: 0,
40
+ };
41
+ }
42
+ const fetchImpl = opts.fetchImpl ?? fetch;
43
+ const timeoutMs = opts.timeoutMs ?? 8000;
44
+ const t0 = Date.now();
45
+ const ctrl = new AbortController();
46
+ const timer = setTimeout(() => ctrl.abort(), timeoutMs);
47
+ try {
48
+ const res = await fetchImpl(url, {
49
+ method: "HEAD",
50
+ redirect: "follow",
51
+ signal: ctrl.signal,
52
+ headers: { "user-agent": opts.userAgent ?? "Mneme-vendor-probe/1.98 (+https://github.com/patsa2561-art/mneme-ai)" },
53
+ });
54
+ clearTimeout(timer);
55
+ const elapsedMs = Date.now() - t0;
56
+ const finalUrl = res.url || url;
57
+ const originalHost = hostOf(url);
58
+ const finalHost = hostOf(finalUrl);
59
+ const hostChanged = !!(originalHost && finalHost && originalHost !== finalHost);
60
+ let verdict;
61
+ let notes;
62
+ if (res.status === 404) {
63
+ verdict = "NOT_FOUND";
64
+ notes = `404 — vendor URL is dead`;
65
+ }
66
+ else if (res.status === 403 || res.status === 401) {
67
+ verdict = "BLOCKED";
68
+ notes = `${res.status} — vendor likely blocks bots (Cloudflare/UA). Browser-real users still work.`;
69
+ }
70
+ else if (hostChanged) {
71
+ verdict = "REDIRECT_HOST_CHANGE";
72
+ notes = `redirected from ${originalHost} to ${finalHost} — update vendor_strategy.ts homeUrl`;
73
+ }
74
+ else if (res.status >= 200 && res.status < 400) {
75
+ verdict = "OK";
76
+ notes = `reachable (status ${res.status})`;
77
+ }
78
+ else {
79
+ verdict = "NETWORK_ERR";
80
+ notes = `unexpected status ${res.status}`;
81
+ }
82
+ return { vendor: entry.id, url, finalUrl, status: res.status, hostChanged, verdict, notes, elapsedMs };
83
+ }
84
+ catch (e) {
85
+ clearTimeout(timer);
86
+ const elapsedMs = Date.now() - t0;
87
+ return {
88
+ vendor: entry.id, url, finalUrl: null, status: null, hostChanged: false,
89
+ verdict: "NETWORK_ERR", notes: `fetch error: ${e.message}`, elapsedMs,
90
+ };
91
+ }
92
+ }
93
+ /** Probe every registered vendor concurrently. Returns one ProbeResult
94
+ * per vendor. Total elapsed time ≈ slowest probe. */
95
+ export async function probeAllVendors(opts = {}) {
96
+ return Promise.all(VENDOR_REGISTRY.map((v) => probeOne(v, opts)));
97
+ }
98
+ /** Probe results that should ALERT — anything that isn't OK or SKIP. */
99
+ export function failingProbes(results) {
100
+ return results.filter((r) => r.verdict !== "OK" && r.verdict !== "SKIP" && r.verdict !== "BLOCKED");
101
+ }
102
+ /** One-line summary suitable for the pulse / CI logs. */
103
+ export function formatProbePulseLine(results) {
104
+ const groups = { OK: 0, REDIRECT_HOST_CHANGE: 0, NOT_FOUND: 0, NETWORK_ERR: 0, BLOCKED: 0, SKIP: 0 };
105
+ for (const r of results)
106
+ groups[r.verdict]++;
107
+ const failing = failingProbes(results);
108
+ const verdict = failing.length === 0 ? "✓ ALL_OK" : `✗ ${failing.length}_FAILING`;
109
+ return `VENDOR-PROBE ${verdict} · ok=${groups.OK} redirect=${groups.REDIRECT_HOST_CHANGE} 404=${groups.NOT_FOUND} blocked=${groups.BLOCKED} skip=${groups.SKIP} err=${groups.NETWORK_ERR}`;
110
+ }
111
+ //# sourceMappingURL=vendor_probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor_probe.js","sourceRoot":"","sources":["../../src/rainbow/vendor_probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * v1.98.0 -- RAINBOW · Vendor strategy map.
3
+ *
4
+ * Replaces the broken "one-size-fits-all RELAY" assumption with explicit
5
+ * per-vendor strategies. Each vendor (web AI, mobile app, MCP-capable
6
+ * editor, etc.) gets the transport that ACTUALLY works for its
7
+ * capability tier.
8
+ *
9
+ * Strategies:
10
+ * clipboard-first — copy plain text + open vendor home page. User pastes.
11
+ * Works on EVERY Web AI's free tier. The default.
12
+ * plain-qr — render plain-text soul as QR (NO encryption, NO
13
+ * fetch-instruction). Phone scans → copies → pastes.
14
+ * mcp-direct — vendor is MCP-aware (Claude Code, Cursor, Codex CLI,
15
+ * Continue) — Mneme MCP server exposes tools directly.
16
+ * No copy/paste needed.
17
+ * prefill-and-paste— vendor honors ?q= deep link AND has web-fetch
18
+ * (paid-tier ChatGPT Plus / Gemini Advanced). The
19
+ * old RELAY path. Used ONLY when caller explicitly
20
+ * asserts "I have a paid-tier AI with browsing".
21
+ * app-deeplink-NA — vendor mobile app does NOT honor any URL scheme.
22
+ * Mneme cannot help; tell the user honestly.
23
+ *
24
+ * Every entry has `verified` (boolean) + `lastChecked` (ISO date) so
25
+ * stale-URL claims like "Verified May 2026" cannot lie silently. The
26
+ * companion `vendor_probe.ts` actually hits each URL with HEAD + asserts.
27
+ */
28
+ export type VendorStrategy = "clipboard-first" | "plain-qr" | "mcp-direct" | "prefill-and-paste" | "app-deeplink-NA";
29
+ export interface VendorEntry {
30
+ /** Canonical vendor id used across Mneme. */
31
+ id: string;
32
+ /** Display label. */
33
+ label: string;
34
+ /** Primary URL to open (home page for clipboard-first). */
35
+ homeUrl: string;
36
+ /** Default strategy for the FREE tier of this vendor. */
37
+ freeStrategy: VendorStrategy;
38
+ /** Strategy when user explicitly has the paid tier with browsing. */
39
+ paidStrategy: VendorStrategy;
40
+ /** Whether ?q= deep link is verified to work (empirical, not assumed). */
41
+ qParamWorks: boolean;
42
+ /** Whether the vendor offers web-fetch in chat (free tier). */
43
+ webFetchAvailable: boolean;
44
+ /** ISO date the URL was last probed. Updated by vendor_probe.ts. */
45
+ lastChecked: string;
46
+ /** Why we picked this strategy (transparency). */
47
+ reasoning: string;
48
+ }
49
+ /** Canonical vendor table. Source of truth for strategy decisions. */
50
+ export declare const VENDOR_REGISTRY: VendorEntry[];
51
+ export declare function entryOf(id: string): VendorEntry | null;
52
+ /** Decide strategy given vendor + whether user has paid tier. */
53
+ export declare function pickStrategy(vendorId: string, opts?: {
54
+ paidTier?: boolean;
55
+ }): {
56
+ strategy: VendorStrategy;
57
+ entry: VendorEntry | null;
58
+ reason: string;
59
+ };
60
+ /** Render the strategy decision as a pulse line. */
61
+ export declare function formatStrategyPulseLine(vendorId: string, opts?: {
62
+ paidTier?: boolean;
63
+ }): string;
64
+ //# sourceMappingURL=vendor_strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor_strategy.d.ts","sourceRoot":"","sources":["../../src/rainbow/vendor_strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG,UAAU,GAAG,YAAY,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAErH,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,YAAY,EAAE,cAAc,CAAC;IAC7B,qEAAqE;IACrE,YAAY,EAAE,cAAc,CAAC;IAC7B,0EAA0E;IAC1E,WAAW,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,sEAAsE;AACtE,eAAO,MAAM,eAAe,EAAE,WAAW,EA+GxC,CAAC;AAEF,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAEtD;AAED,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG;IAAE,QAAQ,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAKzJ;AAED,oDAAoD;AACpD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CAGnG"}