pi-mega-compact 0.20.56 → 0.20.57

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 (80) hide show
  1. package/dist/config/repo-corpus.js +20 -0
  2. package/dist/config/vector-cortex.js +3 -0
  3. package/dist/config.js +1 -1
  4. package/dist/extensions/dashboard-server/api-contracts/endpoints/registry-ext.js +7 -0
  5. package/dist/extensions/dashboard-server/api-contracts/repo-corpus.js +10 -0
  6. package/dist/extensions/dashboard-server/route-dispatch.js +3 -1
  7. package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +1 -0
  8. package/dist/extensions/dashboard-server/routes-repo-corpus.js +258 -0
  9. package/dist/extensions/dashboard-server/routes.js +1 -0
  10. package/dist/src/config/repo-corpus.js +20 -0
  11. package/dist/src/config/vector-cortex.js +3 -0
  12. package/dist/src/config.js +1 -1
  13. package/extensions/dashboard-client/dist/assets/{AreaChart-DlndN0p2.js → AreaChart-CtJ6dSMT.js} +2 -2
  14. package/extensions/dashboard-client/dist/assets/{AreaChart-DlndN0p2.js.map → AreaChart-CtJ6dSMT.js.map} +1 -1
  15. package/extensions/dashboard-client/dist/assets/{BarChart-DH6rZ60s.js → BarChart-DJ3j3xDz.js} +2 -2
  16. package/extensions/dashboard-client/dist/assets/{BarChart-DH6rZ60s.js.map → BarChart-DJ3j3xDz.js.map} +1 -1
  17. package/extensions/dashboard-client/dist/assets/{CacheTab-Qj_NYKw3.js → CacheTab-CXU1_9lR.js} +2 -2
  18. package/extensions/dashboard-client/dist/assets/{CacheTab-Qj_NYKw3.js.map → CacheTab-CXU1_9lR.js.map} +1 -1
  19. package/extensions/dashboard-client/dist/assets/{EventsTab-3QlIPMFj.js → EventsTab-DF-Q3o7x.js} +2 -2
  20. package/extensions/dashboard-client/dist/assets/{EventsTab-3QlIPMFj.js.map → EventsTab-DF-Q3o7x.js.map} +1 -1
  21. package/extensions/dashboard-client/dist/assets/{HealthTab-DTwitpIb.js → HealthTab-Dr1HGOkl.js} +2 -2
  22. package/extensions/dashboard-client/dist/assets/{HealthTab-DTwitpIb.js.map → HealthTab-Dr1HGOkl.js.map} +1 -1
  23. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DkVlBnp7.js → MaintenanceTab-zKhR18_s.js} +2 -2
  24. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DkVlBnp7.js.map → MaintenanceTab-zKhR18_s.js.map} +1 -1
  25. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-B-pHH85r.js → MemoryMapTab-DekIzfn2.js} +2 -2
  26. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-B-pHH85r.js.map → MemoryMapTab-DekIzfn2.js.map} +1 -1
  27. package/extensions/dashboard-client/dist/assets/{MetricsTab-C8VpwhJN.js → MetricsTab-CEKajY38.js} +2 -2
  28. package/extensions/dashboard-client/dist/assets/{MetricsTab-C8VpwhJN.js.map → MetricsTab-CEKajY38.js.map} +1 -1
  29. package/extensions/dashboard-client/dist/assets/{OverviewTab-C_JZlM_Q.js → OverviewTab-24sG8xiE.js} +2 -2
  30. package/extensions/dashboard-client/dist/assets/{OverviewTab-C_JZlM_Q.js.map → OverviewTab-24sG8xiE.js.map} +1 -1
  31. package/extensions/dashboard-client/dist/assets/{ReposTab-rRMlub-E.js → ReposTab-70gkV8l9.js} +2 -2
  32. package/extensions/dashboard-client/dist/assets/{ReposTab-rRMlub-E.js.map → ReposTab-70gkV8l9.js.map} +1 -1
  33. package/extensions/dashboard-client/dist/assets/{SessionsTab-CL6S094G.js → SessionsTab-B3quvYPZ.js} +2 -2
  34. package/extensions/dashboard-client/dist/assets/{SessionsTab-CL6S094G.js.map → SessionsTab-B3quvYPZ.js.map} +1 -1
  35. package/extensions/dashboard-client/dist/assets/SetupTab-tbPrrfYx.js +3 -0
  36. package/extensions/dashboard-client/dist/assets/SetupTab-tbPrrfYx.js.map +1 -0
  37. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-B-8NCvzd.js → TimeSavedCard-B6mdtCWE.js} +2 -2
  38. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-B-8NCvzd.js.map → TimeSavedCard-B6mdtCWE.js.map} +1 -1
  39. package/extensions/dashboard-client/dist/assets/{TurnsTab-C2MVgG4N.js → TurnsTab-CmhRJJqr.js} +2 -2
  40. package/extensions/dashboard-client/dist/assets/{TurnsTab-C2MVgG4N.js.map → TurnsTab-CmhRJJqr.js.map} +1 -1
  41. package/extensions/dashboard-client/dist/assets/{VcStatusBadge-CvlS_fvh.js → VcStatusBadge-SDThp0R0.js} +2 -2
  42. package/extensions/dashboard-client/dist/assets/{VcStatusBadge-CvlS_fvh.js.map → VcStatusBadge-SDThp0R0.js.map} +1 -1
  43. package/extensions/dashboard-client/dist/assets/{VectorCortexTab-BXCAzwQm.js → VectorCortexTab-DDjCkTjk.js} +2 -2
  44. package/extensions/dashboard-client/dist/assets/{VectorCortexTab-BXCAzwQm.js.map → VectorCortexTab-DDjCkTjk.js.map} +1 -1
  45. package/extensions/dashboard-client/dist/assets/{WikiTab-DUivYmJ5.js → WikiTab-Cki48_8N.js} +2 -2
  46. package/extensions/dashboard-client/dist/assets/{WikiTab-DUivYmJ5.js.map → WikiTab-Cki48_8N.js.map} +1 -1
  47. package/extensions/dashboard-client/dist/assets/{button-dTpuinxr.js → button-CojFYd7q.js} +2 -2
  48. package/extensions/dashboard-client/dist/assets/{button-dTpuinxr.js.map → button-CojFYd7q.js.map} +1 -1
  49. package/extensions/dashboard-client/dist/assets/{card-DNwZ7dSg.js → card-Cxeeje9o.js} +2 -2
  50. package/extensions/dashboard-client/dist/assets/{card-DNwZ7dSg.js.map → card-Cxeeje9o.js.map} +1 -1
  51. package/extensions/dashboard-client/dist/assets/{client-extra-CQuCpjyO.js → client-extra-DLxyGxW8.js} +2 -2
  52. package/extensions/dashboard-client/dist/assets/{client-extra-CQuCpjyO.js.map → client-extra-DLxyGxW8.js.map} +1 -1
  53. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-D1HV4d79.js → generateCategoricalChart-DRlqBks2.js} +2 -2
  54. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-D1HV4d79.js.map → generateCategoricalChart-DRlqBks2.js.map} +1 -1
  55. package/extensions/dashboard-client/dist/assets/{index-Bi5YNsLx.js → index-CkbdlPBm.js} +14 -14
  56. package/extensions/dashboard-client/dist/assets/index-CkbdlPBm.js.map +1 -0
  57. package/extensions/dashboard-client/dist/assets/{switch-DiKc2q4n.js → switch-Cx_nl-Ba.js} +2 -2
  58. package/extensions/dashboard-client/dist/assets/{switch-DiKc2q4n.js.map → switch-Cx_nl-Ba.js.map} +1 -1
  59. package/extensions/dashboard-client/dist/assets/{toggle-BBYD10JO.js → toggle-CfIFzp6P.js} +2 -2
  60. package/extensions/dashboard-client/dist/assets/{toggle-BBYD10JO.js.map → toggle-CfIFzp6P.js.map} +1 -1
  61. package/extensions/dashboard-client/dist/assets/{useSSE-CWUSDhIb.js → useSSE-B9_N7ccG.js} +2 -2
  62. package/extensions/dashboard-client/dist/assets/{useSSE-CWUSDhIb.js.map → useSSE-B9_N7ccG.js.map} +1 -1
  63. package/extensions/dashboard-client/dist/index.html +1 -1
  64. package/extensions/dashboard-client/src/tabs/SetupTab/CortexSetup.tsx +2 -0
  65. package/extensions/dashboard-client/src/tabs/SetupTab/VectorCortexRepoCorpusCard.tsx +126 -0
  66. package/extensions/dashboard-client/src/types/repo-corpus.ts +25 -0
  67. package/extensions/dashboard-server/api-contracts/endpoints/registry-ext.ts +11 -0
  68. package/extensions/dashboard-server/api-contracts/index.ts +12 -0
  69. package/extensions/dashboard-server/api-contracts/repo-corpus.ts +76 -0
  70. package/extensions/dashboard-server/route-dispatch.ts +2 -0
  71. package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +6 -0
  72. package/extensions/dashboard-server/routes-repo-corpus.ts +286 -0
  73. package/extensions/dashboard-server/routes.ts +1 -0
  74. package/package.json +1 -1
  75. package/src/config/repo-corpus.ts +23 -0
  76. package/src/config/vector-cortex.ts +3 -0
  77. package/src/config.ts +1 -0
  78. package/extensions/dashboard-client/dist/assets/SetupTab-C6b8YuBK.js +0 -3
  79. package/extensions/dashboard-client/dist/assets/SetupTab-C6b8YuBK.js.map +0 -1
  80. package/extensions/dashboard-client/dist/assets/index-Bi5YNsLx.js.map +0 -1
@@ -357,3 +357,15 @@ export type {
357
357
  CosineFpOverrides,
358
358
  CosineFpReportV1,
359
359
  } from "./cosine-fp.js";
360
+
361
+ // REPO-A — cross-repo corpus status (reader-only)
362
+ export type {
363
+ RepoCorpusStatus,
364
+ RepoCorpusRepoV1,
365
+ RepoCorpusOverlapV1,
366
+ RepoCorpusManifestV1,
367
+ RepoCorpusConsentStateV1,
368
+ RepoCorpusConsentRowV1,
369
+ RepoCorpusPerRepoStatusV1,
370
+ RepoCorpusStatusV1,
371
+ } from "./repo-corpus.js";
@@ -0,0 +1,76 @@
1
+ /**
2
+ * api-contracts/repo-corpus.ts — REPO-A cross-repo corpus API contract.
3
+ *
4
+ * Reader-only shapes for GET /api/repo-corpus. The corpus manifest is written by
5
+ * the CLI corpus-builder (scripts/repo-corpus/build.mjs) as a PSEUDONYMOUS
6
+ * artifact — repo IDs/counts/digests/cross-repo-overlap descriptors only, never
7
+ * payload content (EVAL-REDACT-002). The canonicalRemote→pseudonym mapping is a
8
+ * pure in-memory function and never leaves the builder. No `any`.
9
+ */
10
+
11
+ /** Derived endpoint status (from vc-status.ts). */
12
+ export type RepoCorpusStatus =
13
+ | "live"
14
+ | "awaiting_data"
15
+ | "deferred"
16
+ | "structural"
17
+ | "off";
18
+
19
+ /** One pseudonymous repo in the corpus manifest. */
20
+ export interface RepoCorpusRepoV1 {
21
+ readonly repoPseudonym: string;
22
+ readonly sessions: number;
23
+ readonly sessionIds: readonly string[];
24
+ readonly events: number;
25
+ /** SHA-256 over the repo's session-id slice + count (content-free). */
26
+ readonly digest: string;
27
+ }
28
+
29
+ /** A recorded cross-repo session overlap descriptor (IDs only, never text). */
30
+ export interface RepoCorpusOverlapV1 {
31
+ readonly repoA: string;
32
+ readonly repoB: string;
33
+ readonly sharedSessions: number;
34
+ readonly sharedIds: readonly string[];
35
+ }
36
+
37
+ /** The corpus manifest the builder emits (pseudonymous). */
38
+ export interface RepoCorpusManifestV1 {
39
+ readonly schema: "repo-corpus-manifest-v1";
40
+ readonly ownerPseudonym: string;
41
+ readonly datasetVersion: string;
42
+ readonly effectiveSeq: number;
43
+ readonly totalEvents: number;
44
+ readonly repos: readonly RepoCorpusRepoV1[];
45
+ readonly overlaps: readonly RepoCorpusOverlapV1[];
46
+ }
47
+
48
+ /** Per-repo consent state projection used by the reader route (pseudonymous). */
49
+ export interface RepoCorpusConsentStateV1 {
50
+ readonly schema: "repo-corpus-consent-state-v1";
51
+ readonly perRepo: readonly RepoCorpusConsentRowV1[];
52
+ }
53
+
54
+ /** One repo's consent row (never payload content). */
55
+ export interface RepoCorpusConsentRowV1 {
56
+ readonly repoPseudonym: string;
57
+ readonly consentedCrossRepo: boolean;
58
+ readonly revokedAt?: string;
59
+ }
60
+
61
+ /** Per-repo status row in RepoCorpusStatusV1. */
62
+ export interface RepoCorpusPerRepoStatusV1 {
63
+ readonly repoPseudonym: string;
64
+ readonly sessions: number;
65
+ readonly consentedCrossRepo: boolean;
66
+ readonly revokedAt?: string;
67
+ }
68
+
69
+ /** Response body for GET /api/repo-corpus. */
70
+ export interface RepoCorpusStatusV1 {
71
+ readonly schema: "repo-corpus-status-v1";
72
+ readonly corpus: RepoCorpusManifestV1 | null;
73
+ readonly perRepo: readonly RepoCorpusPerRepoStatusV1[];
74
+ readonly totalEvents: number;
75
+ readonly status: RepoCorpusStatus;
76
+ }
@@ -64,6 +64,7 @@ import {
64
64
  handleImproveCortexStatus,
65
65
  handleDedupTierAttribution,
66
66
  handleCosineFpReport,
67
+ handleRepoCorpus,
67
68
  } from "./routes.js";
68
69
  // VC6C repair lives in its own module (routes-vector-cortex-repair.ts) so the
69
70
  // heal route file stays well under the 400-line extension soft limit.
@@ -162,5 +163,6 @@ export function dispatchRoutes(
162
163
  if (handleImproveCortexStatus(req, res, ctx)) return true;
163
164
  if (handleDedupTierAttribution(req, res, ctx)) return true;
164
165
  if (handleCosineFpReport(req, res, ctx)) return true;
166
+ if (handleRepoCorpus(req, res, ctx)) return true;
165
167
  return false;
166
168
  }
@@ -324,5 +324,11 @@ export const VECTOR_CORTEX_SETTINGS: SettingGroup = {
324
324
  "Real-corpus L2 cosine FP validation (COS-FP-R): runs the real-corpus grid sweep (scripts/cosine-fp/real-bench.mjs) against donated, consent-approved sessions only (SECURITY_PRIVACY Lifecycle/Consent), scoring FP/FN with Wilson intervals + session-grouped bootstrap, and appends CI-backed per-content-type recommendations to the cosine-threshold report. Runs only when a valid consented corpus exists; absent corpus = no_corpus (normative pre-donation state, nothing written). OFF = script inert, nothing executes, no writes (byte-identical predecessor).",
325
325
  true,
326
326
  ),
327
+ boolDirect(
328
+ "MEGACOMPACT_REPO_CORPUS",
329
+ "Cross-Repo Corpus (REPO-A)",
330
+ "Cross-repo corpus preparation (REPO-A): the governed, consent-gated reader-only path that builds a pseudonymous corpus manifest from per-repo events.log slices and serves GET /api/repo-corpus answering which pseudonymous repos/sessions are in the corpus, what cross-repo overlap exists, and whether consent is active for each — counts + IDs + status only, never payload content. Consent is append-only (consent.mjs, CLI/ops-only); revocation freezes the builder + route. OFF = builder refuses to run, reader route 404s, single-repo recall untouched (byte-identical predecessor).",
331
+ true,
332
+ ),
327
333
  ],
328
334
  };
@@ -0,0 +1,286 @@
1
+ /**
2
+ * dashboard-server/routes-repo-corpus.ts — REPO-A cross-repo corpus status route.
3
+ *
4
+ * GET /api/repo-corpus — reader-only aggregate answering "which pseudonymous
5
+ * repos/sessions are in the consented corpus, what cross-repo overlap exists,
6
+ * and is consent active for each". Reads the corpus manifest + consent-state the
7
+ * CLI corpus-builder (scripts/repo-corpus/build.mjs) produced into the resolved
8
+ * corpus dir, memoized by {mtime,size} key with a 5s TTL (mirrors
9
+ * routes-cosine-fp.ts). Serves counts + IDs + status only — never payload
10
+ * content (EVAL-REDACT-002).
11
+ *
12
+ * IMPORTANT (distribution): this route does NOT import the builder scripts
13
+ * (scripts/ is excluded from package.json `files`). It reads the manifest files
14
+ * the builder wrote; the corpus dir is resolved from MEGACOMPACT_REPO_CORPUS_DIR
15
+ * (operator/test seam) or a bundled asset dir. The contract types ship in
16
+ * api-contracts/repo-corpus.ts.
17
+ *
18
+ * Flag-off (MEGACOMPACT_REPO_CORPUS=0) returns 404 — byte-identical
19
+ * predecessor. Absent corpus → awaiting_data (never a fabricated zero row).
20
+ *
21
+ * Guardrails: PREVENT-PI-004 (local filesystem read only), PREVENT-001
22
+ * (JSON.parse guarded), PREVENT-011 (no `any`).
23
+ */
24
+
25
+ import type { IncomingMessage, ServerResponse } from "node:http";
26
+ import { readFileSync, statSync } from "node:fs";
27
+ import { join, dirname } from "node:path";
28
+ import { fileURLToPath } from "node:url";
29
+ import type { RouteContext } from "./routes-core.js";
30
+ import { sendJson } from "./routes-vector-cortex-shared.js";
31
+ import { REPO_CORPUS_ENABLED } from "../../src/config.js";
32
+ import { deriveVcStatus } from "./vc-status.js";
33
+ import type {
34
+ RepoCorpusManifestV1,
35
+ RepoCorpusStatusV1,
36
+ RepoCorpusConsentStateV1,
37
+ RepoCorpusPerRepoStatusV1,
38
+ } from "./api-contracts/repo-corpus.js";
39
+
40
+ const MEMO_TTL_MS = 5000; // ≤5s per file state
41
+ const MANIFEST_FILENAME = "manifest.json";
42
+ const CONSENT_STATE_FILENAME = "consent-state.json";
43
+
44
+ interface MemoEntry {
45
+ key: string;
46
+ at: number;
47
+ body: RepoCorpusStatusV1;
48
+ }
49
+
50
+ let memo: MemoEntry | null = null;
51
+
52
+ /**
53
+ * Resolve the directory containing the corpus manifest + consent-state.
54
+ * 1. MEGACOMPACT_REPO_CORPUS_DIR (operator/test seam) — the canonical runtime
55
+ * location where an operator ran the builder (or a test points a temp dir).
56
+ * 2. Bundled asset extension/dashboard-server/assets/ — the shipped location,
57
+ * so a pre-built corpus can be shipped in the tarball (PREVENT-DIST-001);
58
+ * tsc does not copy .json into dist, so probe co-located + repo-root.
59
+ * 3. Git-checkout well-known dir for dev use (scripts/repo-corpus/corpus-run/).
60
+ * Returns null when unresolvable — caller serves awaiting_data.
61
+ */
62
+ export function repoCorpusDir(): string | null {
63
+ const override = process.env.MEGACOMPACT_REPO_CORPUS_DIR;
64
+ if (override) return override;
65
+ const here = dirname(fileURLToPath(import.meta.url));
66
+ const bundledCandidates = [
67
+ join(here, "assets"),
68
+ join(here, "..", "..", "..", "extensions", "dashboard-server", "assets"),
69
+ ];
70
+ for (const bundled of bundledCandidates) {
71
+ try {
72
+ // guardrails-allow PREVENT-PI-004: local bundled manifest stat (loopback)
73
+ statSync(join(bundled, MANIFEST_FILENAME));
74
+ return bundled;
75
+ } catch {
76
+ /* try next candidate, then fall through to git-checkout walk */
77
+ }
78
+ }
79
+ // Git-checkout corpus dir — dev path only.
80
+ let dir = here;
81
+ const rel = join("scripts", "repo-corpus", "corpus-run");
82
+ for (let i = 0; i < 8; i++) {
83
+ const candidate = join(dir, rel);
84
+ try {
85
+ // guardrails-allow PREVENT-PI-004: local corpus-run dir stat (loopback)
86
+ statSync(candidate);
87
+ return candidate;
88
+ } catch {
89
+ /* keep walking */
90
+ }
91
+ const next = dirname(dir);
92
+ if (next === dir) break;
93
+ dir = next;
94
+ }
95
+ return null;
96
+ }
97
+
98
+ /** Guarded JSON file read → parsed value or null (PREVENT-001, PREVENT-011). */
99
+ function readJsonFile(p: string): unknown {
100
+ let raw: string;
101
+ try {
102
+ raw = readFileSync(p, "utf8"); // guardrails-allow PREVENT-PI-004: local corpus file read (loopback)
103
+ } catch {
104
+ return null;
105
+ }
106
+ let parsed: unknown;
107
+ try {
108
+ parsed = JSON.parse(raw);
109
+ } catch {
110
+ return null;
111
+ }
112
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
113
+ return parsed;
114
+ }
115
+
116
+ function isRecord(v: unknown): v is Record<string, unknown> {
117
+ return !!v && typeof v === "object" && !Array.isArray(v);
118
+ }
119
+
120
+ /** Project a raw consent-state file (structurally guarded, PREVENT-011). */
121
+ function readConsentState(corpusDir: string): RepoCorpusConsentStateV1 | null {
122
+ const raw = readJsonFile(join(corpusDir, CONSENT_STATE_FILENAME));
123
+ if (!isRecord(raw)) return null;
124
+ const perRepo = Array.isArray(raw.perRepo) ? raw.perRepo : [];
125
+ const rows = perRepo
126
+ .filter(isRecord)
127
+ .map((r) => ({
128
+ repoPseudonym:
129
+ typeof r.repoPseudonym === "string" ? r.repoPseudonym : "",
130
+ consentedCrossRepo: r.consentedCrossRepo === true || r.consentedCrossRepo === "true",
131
+ revokedAt: typeof r.revokedAt === "string" ? r.revokedAt : undefined,
132
+ }))
133
+ .filter((r) => r.repoPseudonym.length > 0);
134
+ return { schema: "repo-corpus-consent-state-v1", perRepo: rows };
135
+ }
136
+
137
+ /** Project a raw manifest file (structurally guarded, PREVENT-011). */
138
+ function readManifest(corpusDir: string): RepoCorpusManifestV1 | null {
139
+ const raw = readJsonFile(join(corpusDir, MANIFEST_FILENAME));
140
+ if (!isRecord(raw)) return null;
141
+ if (raw.schema !== "repo-corpus-manifest-v1") return null;
142
+ const repos = Array.isArray(raw.repos)
143
+ ? raw.repos
144
+ .filter(isRecord)
145
+ .map((r) => ({
146
+ repoPseudonym:
147
+ typeof r.repoPseudonym === "string" ? r.repoPseudonym : "",
148
+ sessions: typeof r.sessions === "number" ? r.sessions : 0,
149
+ sessionIds: Array.isArray(r.sessionIds)
150
+ ? r.sessionIds.filter((x): x is string => typeof x === "string")
151
+ : [],
152
+ events: typeof r.events === "number" ? r.events : 0,
153
+ digest: typeof r.digest === "string" ? r.digest : "",
154
+ }))
155
+ .filter((r) => r.repoPseudonym.length > 0)
156
+ : [];
157
+ const overlaps = Array.isArray(raw.overlaps)
158
+ ? raw.overlaps
159
+ .filter(isRecord)
160
+ .map((o) => ({
161
+ repoA: typeof o.repoA === "string" ? o.repoA : "",
162
+ repoB: typeof o.repoB === "string" ? o.repoB : "",
163
+ sharedSessions: typeof o.sharedSessions === "number" ? o.sharedSessions : 0,
164
+ sharedIds: Array.isArray(o.sharedIds)
165
+ ? o.sharedIds.filter((x): x is string => typeof x === "string")
166
+ : [],
167
+ }))
168
+ .filter((o) => o.repoA.length > 0 && o.repoB.length > 0)
169
+ : [];
170
+ return {
171
+ schema: "repo-corpus-manifest-v1",
172
+ ownerPseudonym:
173
+ typeof raw.ownerPseudonym === "string" ? raw.ownerPseudonym : "",
174
+ datasetVersion:
175
+ typeof raw.datasetVersion === "string" ? raw.datasetVersion : "",
176
+ effectiveSeq: typeof raw.effectiveSeq === "number" ? raw.effectiveSeq : 0,
177
+ totalEvents: typeof raw.totalEvents === "number" ? raw.totalEvents : 0,
178
+ repos,
179
+ overlaps,
180
+ };
181
+ }
182
+
183
+ /**
184
+ * Build the perRepo status rows. A repo whose consent cannot be confirmed
185
+ * (missing from consent-state, or missing stateDir at the builder) degrades to
186
+ * consentedCrossRepo:false — never a crash, never a silent inclusion.
187
+ */
188
+ function buildPerRepo(
189
+ manifest: RepoCorpusManifestV1,
190
+ consent: RepoCorpusConsentStateV1 | null,
191
+ ): RepoCorpusPerRepoStatusV1[] {
192
+ const consentByRepo = new Map<string, RepoCorpusConsentStateV1["perRepo"][number]>();
193
+ if (consent) {
194
+ for (const row of consent.perRepo) consentByRepo.set(row.repoPseudonym, row);
195
+ }
196
+ return manifest.repos.map((r) => {
197
+ const c = consentByRepo.get(r.repoPseudonym);
198
+ return {
199
+ repoPseudonym: r.repoPseudonym,
200
+ sessions: r.sessions,
201
+ consentedCrossRepo: c ? c.consentedCrossRepo : false,
202
+ revokedAt: c && c.revokedAt ? c.revokedAt : undefined,
203
+ };
204
+ });
205
+ }
206
+
207
+ function buildBody(corpusDir: string, manifest: RepoCorpusManifestV1): RepoCorpusStatusV1 {
208
+ const consent = readConsentState(corpusDir);
209
+ const perRepo = buildPerRepo(manifest, consent);
210
+ const hasData = manifest.repos.length > 0;
211
+ const status = deriveVcStatus({ enabled: true, hasData, structuralOnly: false });
212
+ return {
213
+ schema: "repo-corpus-status-v1",
214
+ corpus: manifest,
215
+ perRepo,
216
+ totalEvents: manifest.totalEvents,
217
+ status,
218
+ };
219
+ }
220
+
221
+ function awaitingDataBody(): RepoCorpusStatusV1 {
222
+ const status = deriveVcStatus({
223
+ enabled: true,
224
+ hasData: false,
225
+ structuralOnly: false,
226
+ });
227
+ return {
228
+ schema: "repo-corpus-status-v1",
229
+ corpus: null,
230
+ perRepo: [],
231
+ totalEvents: 0,
232
+ status,
233
+ };
234
+ }
235
+
236
+ export function handleRepoCorpus(
237
+ req: IncomingMessage,
238
+ res: ServerResponse,
239
+ _ctx: RouteContext,
240
+ ): boolean {
241
+ const url = req.url ?? "";
242
+ if (url !== "/api/repo-corpus") return false;
243
+ if (req.method !== "GET") {
244
+ sendJson(res, 405, { error: "method_not_allowed" });
245
+ return true;
246
+ }
247
+ if (!REPO_CORPUS_ENABLED()) {
248
+ // Flag-off: 404 — byte-identical predecessor.
249
+ sendJson(res, 404, { error: "not_found" });
250
+ return true;
251
+ }
252
+
253
+ const corpusDir = repoCorpusDir();
254
+ if (corpusDir === null) {
255
+ sendJson(res, 200, awaitingDataBody());
256
+ return true;
257
+ }
258
+
259
+ // Memoized-facts pattern: serve a still-fresh entry keyed on {mtime,size}.
260
+ let size = 0;
261
+ let mtime = 0;
262
+ try {
263
+ const s = statSync(join(corpusDir, MANIFEST_FILENAME)); // guardrails-allow PREVENT-PI-004: local stat (loopback)
264
+ size = s.size;
265
+ mtime = s.mtimeMs;
266
+ } catch {
267
+ // no manifest on disk yet
268
+ }
269
+ if (size === 0 && mtime === 0) {
270
+ sendJson(res, 200, awaitingDataBody());
271
+ return true;
272
+ }
273
+
274
+ const key = `${mtime}:${size}`;
275
+ const now = Date.now();
276
+ if (memo !== null && memo.key === key && now - memo.at <= MEMO_TTL_MS) {
277
+ sendJson(res, 200, memo.body);
278
+ return true;
279
+ }
280
+
281
+ const manifest = readManifest(corpusDir);
282
+ const body = manifest === null ? awaitingDataBody() : buildBody(corpusDir, manifest);
283
+ memo = { key, at: now, body };
284
+ sendJson(res, 200, body);
285
+ return true;
286
+ }
@@ -68,3 +68,4 @@ export {
68
68
  } from "./routes-cortex-improve.js";
69
69
  export { handleDedupTierAttribution } from "./routes-dedup-attribution.js";
70
70
  export { handleCosineFpReport } from "./routes-cosine-fp.js";
71
+ export { handleRepoCorpus } from "./routes-repo-corpus.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-mega-compact",
3
- "version": "0.20.56",
3
+ "version": "0.20.57",
4
4
  "description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
5
5
  "type": "module",
6
6
  "license": "BSD-3-Clause",
@@ -0,0 +1,23 @@
1
+ /**
2
+ * config/repo-corpus.ts — REPO-A cross-repo corpus preparation sprint flag.
3
+ *
4
+ * Positive sprint flag sibling (mirrors config/vector-cortex-cosfp.ts), NOT under
5
+ * a vector-cortex- prefix per the REPO-A spec: the reader route + corpus-builder
6
+ * gate on this flag. Root src/config.ts re-exports it so every existing import
7
+ * keeps resolving unchanged. Pi-agnostic, dependency-free (PREVENT-PI-004 /
8
+ * PREVENT-011).
9
+ */
10
+
11
+ import { sprintFlag } from "./vector-cortex-flag.js";
12
+
13
+ /**
14
+ * REPO-A — cross-repo corpus preparation. Default ON.
15
+ * `MEGACOMPACT_REPO_CORPUS=0` disables and is byte-identical to the predecessor:
16
+ * the reader route GET /api/repo-corpus 404s (no derived artifact written), the
17
+ * corpus-builder refuses to run, and the existing single-repo recall path is
18
+ * untouched. This flag MUST also be a dashboard SETTINGS toggle (visible in the
19
+ * config UI, never in EXCLUDED_SETTINGS). The builder + route perform only local
20
+ * filesystem reads / local `git` introspection (PREVENT-PI-004).
21
+ */
22
+ export const REPO_CORPUS_ENABLED = (): boolean =>
23
+ sprintFlag("MEGACOMPACT_REPO_CORPUS");
@@ -66,6 +66,9 @@ export { ENC_0G_ENABLED } from "./vector-cortex-enc0g.js";
66
66
  export { COSINE_FP_BENCH_ENABLED } from "./vector-cortex-cosfp.js";
67
67
  // COS-FP-R real-corpus FP validation flag extracted to vector-cortex-cosfp-real.ts.
68
68
  export { COSINE_FP_REAL_ENABLED } from "./vector-cortex-cosfp-real.js";
69
+ // REPO-A cross-repo corpus prep flag extracted to repo-corpus.ts (no vector-cortex
70
+ // prefix per spec); re-exported so root src/config.ts barrel resolves unchanged.
71
+ export { REPO_CORPUS_ENABLED } from "./repo-corpus.js";
69
72
  export { ENC_1A_ENABLED } from "./vector-cortex-enc1a.js";
70
73
  export {
71
74
  ENC_1B_ENABLED,
package/src/config.ts CHANGED
@@ -204,6 +204,7 @@ export {
204
204
  ENC_2BUDGET_DEFAULT_MIB,
205
205
  COSINE_FP_BENCH_ENABLED,
206
206
  COSINE_FP_REAL_ENABLED,
207
+ REPO_CORPUS_ENABLED,
207
208
  BREAKER_WINDOW_MS,
208
209
  BREAKER_MIN_ATTEMPTS,
209
210
  BREAKER_PERF_FAILURES,
@@ -1,3 +0,0 @@
1
- import{r as s,j as e,h as O,i as Q,k as Y,p as ne,l as re,m as ae,C as le,n as oe,o as ie,q as ce,s as Z,t as X,v as de,u as me,w as ue,A as he}from"./index-Bi5YNsLx.js";import{S as fe}from"./switch-DiKc2q4n.js";import{f as ge,p as pe,d as xe}from"./client-extra-CQuCpjyO.js";import{V as be}from"./VcStatusBadge-CvlS_fvh.js";import{T as ye}from"./toggle-BBYD10JO.js";function je(t){try{return new Date(t*1e3).toLocaleString()}catch{return"—"}}function ee({achievements:t}){const r=s.useRef(0),[n,l]=s.useState(null),a=t.reduce((i,m)=>Math.max(i,m.unlocked_at??0),0),o=r.current;s.useEffect(()=>{a>r.current&&(r.current=a)},[a]),s.useEffect(()=>{if(o>0&&a>o){const i=t.filter(m=>m.unlocked_at!=null&&(m.unlocked_at??0)>o);if(i.length>0){const m=i.map(d=>`${d.icon??""} ${d.title}`.trim()).join(", ")+" unlocked!";l(m);const g=setTimeout(()=>l(null),4e3);return()=>clearTimeout(g)}}},[t,a,o]);const h=t.filter(i=>!(i.hidden===1&&i.unlocked_at==null));return e.jsxs("div",{className:"ach-section",children:[n!=null&&e.jsx("div",{className:"ach-toast show",children:n}),e.jsxs("div",{className:"ach-tiles",children:[h.length===0&&e.jsx("span",{className:"repo-none",children:"no achievements yet"}),h.map(i=>{if(i.unlocked_at!=null){const m=o>0&&(i.unlocked_at??0)>o;return e.jsxs("div",{className:`ach-tile unlocked${m?" just-unlocked":""}`,children:[i.icon??""," ",i.title,e.jsxs("span",{className:"ach-detail",children:["unlocked ",je(i.unlocked_at)]})]},i.id)}return e.jsxs("div",{className:"ach-tile locked",children:["??? ",i.title]},i.id)})]})]})}function D(t){return(Math.round(t*10)/10).toString()+"%"}function F(t){return t!=null?new Date(t).toLocaleString():"—"}function H(t){return t&&typeof t=="object"?t:{}}function ve(t){return t.split("/").pop()||t}function _({title:t,rows:r,badge:n,renderValue:l}){return e.jsxs("div",{className:"lb-card",children:[e.jsxs("h3",{children:[t,n]}),r.length===0?e.jsx("div",{className:"lb-empty",children:"—"}):e.jsx("table",{children:e.jsx("tbody",{children:r.map((a,o)=>e.jsxs("tr",{children:[e.jsx("td",{title:a.repo_root,children:ve(a.repo_root)}),e.jsx("td",{className:"num",children:l(a)})]},`${a.repo_root}-${o}`))})})]})}function Se(){const[t,r]=s.useState({}),[n,l]=s.useState(0),[a,o]=s.useState([]),[h,i]=s.useState(!1),[m,g]=s.useState(!0),[d,b]=s.useState(null),c=s.useRef(0),u=s.useCallback(async()=>{try{const[j,x,T,B,U,W]=await Promise.all([O({metric:"cache",limit:25}),O({metric:"dedupe",limit:25}),O({metric:"turns",limit:25}),O({metric:"mega_cache",limit:25}),O({metric:"repos",limit:1}),Q()]),P=B.find(I=>I.ts>c.current&&I.value>100);c.current>0&&P&&(b(`oopsie! cache went to ${Math.round(P.value)}% — MEGA CACHE 🥧`),setTimeout(()=>b(null),4e3)),B.length>0&&(c.current=Math.max(...B.map(I=>I.ts))),r({cache:j,dedupe:x,turns:T,mega_cache:B}),l(U[0]?.value??0),o(W)}catch{}finally{g(!1)}},[]);s.useEffect(()=>{let j=!0;const x=async()=>{j&&await u()};x();const T=setInterval(()=>void x(),15e3);return()=>{j=!1,clearInterval(T)}},[u]),s.useEffect(()=>{let j=!0;const x=async()=>{try{const B=await Y();j&&(i(!!B.game_mode_on),B.theme&&(document.documentElement.dataset.theme=B.theme))}catch{}};x();const T=setInterval(()=>void x(),15e3);return()=>{j=!1,clearInterval(T)}},[]);const y=t.mega_cache??[];let v=null,w=null;for(const j of y){(v==null||j.value>v)&&(v=j.value);const x=H(j.meta),T=x.firstSeenTs??x.firstSeen??j.ts;(w==null||T<w)&&(w=T)}const C=v!=null&&v>100,p=t.turns??[],E=p.reduce((j,x)=>Math.max(j,x.value),0),N=Math.floor(Math.log2(E+1))+1,M=(t.cache?.length??0)>0||(t.dedupe?.length??0)>0||p.length>0||y.length>0||n>0;return e.jsxs("div",{className:`game-tab${h?" game-mode-on":""}`,children:[d!=null&&e.jsx("div",{className:"mega-cache-toast show",children:d}),C&&e.jsxs("div",{className:"mega-cache-banner",children:["🥧"," MEGA CACHE! peak ",D(v)," — first reached ",F(w)]}),C&&e.jsxs("div",{className:"achievement-tile unlocked",children:["🏆"," Opie's Wild Ride",e.jsxs("span",{className:"ach-detail",children:["best ",D(v)," · first ",F(w)]})]}),e.jsx("h2",{children:"High Scores"}),!M&&!m&&e.jsx("div",{className:"game-empty",children:"No scores yet — run a session with game mode on."}),M&&e.jsxs("div",{className:"game-leaderboards",children:[e.jsx(_,{title:"Cache %",rows:t.cache??[],renderValue:j=>D(j.value)}),e.jsx(_,{title:"Dedupe (collapsed)",rows:t.dedupe??[],renderValue:j=>j.value.toLocaleString()}),e.jsx(_,{title:"Turns",rows:p,badge:p.length>0?e.jsxs("span",{className:"lvl-badge",children:["LVL ",N]}):void 0,renderValue:j=>j.value.toLocaleString()}),e.jsx(_,{title:"MEGA CACHE trophies",rows:y,renderValue:j=>e.jsxs(e.Fragment,{children:[D(j.value),e.jsx("span",{className:"lb-meta",children:F(H(j.meta).firstSeenTs??H(j.meta).firstSeen??j.ts)})]})})]}),n>0&&e.jsx("div",{className:"repos-badge-line",children:e.jsxs("span",{className:"repos-badge",children:[n," repos"]})}),e.jsx("h3",{children:"Achievements"}),e.jsx(ee,{achievements:a})]})}function we(){const[t,r]=s.useState([]),[n,l]=s.useState(!0),[a,o]=s.useState(null),h=s.useCallback(async()=>{try{const i=await Q();r(i),o(null)}catch(i){o(i instanceof Error?i:new Error(String(i)))}finally{l(!1)}},[]);return s.useEffect(()=>{let i=!0;const m=async()=>{i&&await h()};m();const g=setInterval(()=>void m(),15e3);return()=>{i=!1,clearInterval(g)}},[h]),n&&t.length===0?e.jsx("div",{className:"tab-stub",children:"Loading achievements…"}):a&&t.length===0?e.jsxs("div",{className:"tab-stub",children:["Error: ",a.message]}):e.jsxs("div",{className:"achievements-tab",children:[e.jsx("h2",{children:"Achievements"}),e.jsx(ee,{achievements:t})]})}const te=[{id:"transparent",label:"Transparent (accents only)",css:{bg:null,fg:"#c9d1d9",accent:"#3fb950",mega:"#f0883e"},ansi:{bg:null,fg:"39",accent:"32",mega:"33"}},{id:"retro",label:"Retro 8-bit green",css:{bg:"#003300",fg:"#33ff33",accent:"#00ff41",mega:"#39ff14"},ansi:{bg:"40",fg:"92",accent:"92",mega:"1;92"}},{id:"orange-bold",label:"Orange bold",css:{bg:"#1a0f00",fg:"#ff8c00",accent:"#ff6b00",mega:"#ff4500"},ansi:{bg:"48;5;52",fg:"38;5;208",accent:"38;5;208",mega:"1;38;5;202"}},{id:"cyan-neon",label:"Cyan neon",css:{bg:"#001a1a",fg:"#00ffff",accent:"#22d3ee",mega:"#7df9ff"},ansi:{bg:"48;5;23",fg:"38;5;51",accent:"38;5;51",mega:"1;38;5;51"}},{id:"amber-mono",label:"Amber phosphor",css:{bg:"#1a1200",fg:"#ffb000",accent:"#ff8c00",mega:"#ff5500"},ansi:{bg:"48;5;58",fg:"38;5;214",accent:"38;5;214",mega:"1;38;5;208"}},{id:"grayscale",label:"Grayscale minimal",css:{bg:"#161616",fg:"#b0b0b0",accent:"#8b949e",mega:"#e6edf3"},ansi:{bg:"48;5;235",fg:"38;5;249",accent:"38;5;249",mega:"1;38;5;255"}}],G=te.map(t=>t.id),z={gameMode:"Turn game mode on/off (themes the widget + dashboard)",theme:"Visual theme (applies instantly)",tuiMode:"TUI widget display density",tier:"Live pressure band — climbs low→mega as context fills the window.",preset:"The env-resolved base compaction preset (low/medium/high/ultra/mega) that set the token threshold.",pressure:"Live pressure = currentTokens / threshold — % of the model context window (threshold fires at the tier's % of window).",threshold:"Compaction threshold = tierPct × model context window — mega-compact trims BELOW pi's native ~80% auto-compact for any model size.",fastGate:"Fast-gate arming floor — the live trim arms once context passes this % of the window."};function ke(t,r,n){let l=t.toLocaleString();return r!=null&&n>0&&(l+=` (${Math.round(r*100)}% of ${n.toLocaleString()})`),l}function Ce(t){return`${Math.round((t||0)*100)}%`}function Ne(){const[t,r]=s.useState(null),[n,l]=s.useState(null),[a,o]=s.useState(!1);s.useEffect(()=>{let c=!0;const u=async()=>{try{const v=await re();c&&r(v)}catch{}};u();const y=setInterval(()=>void u(),5e3);return()=>{c=!1,clearInterval(y)}},[]),s.useEffect(()=>{let c=!0;const u=async()=>{try{const v=await Y();c&&(l(v),v.theme&&(document.documentElement.dataset.theme=v.theme))}catch{}};u();const y=setInterval(()=>void u(),5e3);return()=>{c=!1,clearInterval(y)}},[]);const h=s.useCallback(async c=>{o(!0);try{const u=await ne(c);l(u),u.theme&&(document.documentElement.dataset.theme=u.theme)}catch{}o(!1)},[]),i=n?.game_mode_on??!1,m=n?.theme??"transparent",g=n?.tui_display_mode??"full",d=t?.config,b=t?.context.contextWindow??0;return e.jsxs("div",{className:"config-tab",children:[e.jsxs("section",{className:"config-settings",children:[e.jsx("h3",{children:"Settings"}),e.jsx("div",{className:"settings-row",children:e.jsxs("label",{title:z.gameMode,children:[e.jsx("input",{type:"checkbox",checked:i,onChange:c=>h({game_mode_on:c.currentTarget.checked}),disabled:a}),"Game Mode"]})}),e.jsx("div",{className:"settings-row",children:e.jsxs("label",{title:z.theme,children:["Theme",e.jsx("select",{value:m,onChange:c=>h({theme:c.currentTarget.value}),disabled:a,children:te.map(c=>e.jsx("option",{value:c.id,children:c.label},c.id))}),e.jsx("button",{type:"button",disabled:a,className:"theme-cycle-btn",title:"Cycle to the next theme (P3)",onClick:()=>{const c=G.indexOf(m),u=G[(c<0?0:c+1)%G.length];u&&h({theme:u})},children:"Next theme →"})]})}),e.jsx("div",{className:"settings-row",children:e.jsxs("label",{title:z.tuiMode,children:["TUI Mode",e.jsxs("select",{value:g,onChange:c=>h({tui_display_mode:c.currentTarget.value}),disabled:a,children:[e.jsx("option",{value:"full",children:"Full"}),e.jsx("option",{value:"minimal",children:"Minimal"})]})," ",e.jsx("span",{className:"tui-mode-hint",children:"(affects the in-app TUI widget; not shown here)"})]})})]}),e.jsxs("section",{className:"config-display",children:[e.jsx("h3",{children:"Configuration"}),e.jsxs("div",{className:"config-grid",children:[e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",title:z.tier,children:"Tier"}),e.jsx("span",{className:"config-value",children:t?`${t.tier} (live)`:"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",title:z.preset,children:"Preset"}),e.jsx("span",{className:"config-value",children:t?.presetTier??"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",title:z.pressure,children:"Pressure"}),e.jsx("span",{className:"config-value",children:t?Ce(t.pressure):"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",title:z.threshold,children:"Threshold"}),e.jsx("span",{className:"config-value",children:d?ke(d.thresholdTokens,d.tierPct,b):"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",title:z.fastGate,children:"Fast Gate"}),e.jsx("span",{className:"config-value",children:d?`${d.fastGatePct}%`:"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",children:"Auto"}),e.jsx("span",{className:"config-value",children:d?d.auto?"enabled":"disabled":"—"})]}),e.jsxs("div",{className:"config-item",children:[e.jsx("span",{className:"config-label",children:"Anchor"}),e.jsx("span",{className:"config-value",children:d?.anchorUserMessages??"—"})]})]})]})]})}const A={section:{background:"#1a1a2e",borderRadius:"8px",padding:"1rem",marginBottom:"1rem",border:"1px solid #2a2a4e"},sectionTitle:{fontSize:"1.1rem",fontWeight:700,marginTop:0,marginBottom:"0.75rem",color:"#e0e0e0",borderBottom:"1px solid #333",paddingBottom:"0.5rem"},label:{fontWeight:600,color:"#a0a0c0",marginRight:"0.5rem"},value:{color:"#e0e0e0"},row:{marginBottom:"0.4rem",fontSize:"0.9rem"}};function Ee(){const[t,r]=s.useState(null),[n,l]=s.useState(null),a=s.useCallback(()=>{ae().then(r).catch(g=>l(g instanceof Error?g.message:String(g)))},[]);s.useEffect(()=>{a()},[a]),s.useEffect(()=>{const g=setInterval(a,3e4);return()=>clearInterval(g)},[a]);const o=t?.status==="ok",h=t?.status==="ok"?"Working":t?.status==="unreachable"?"Unreachable":"Error",i=o?"#4caf50":"#f44336",m=o?"✓":"✗";return e.jsxs("div",{style:A.section,children:[e.jsx("h3",{style:A.sectionTitle,children:"Embedder Health"}),n&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error: ",n]}),!t&&!n&&e.jsx("p",{style:{color:"#888",fontSize:"0.85rem"},children:"Probing embedder..."}),t&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:A.row,children:[e.jsxs("span",{style:{...A.label,color:`${i}`},children:[m," ",h,":"]}),e.jsxs("span",{style:A.value,children:[t.dim," dims"]}),t.latencyMs!==void 0&&e.jsxs("span",{style:{color:"#a0a0c0",marginLeft:"0.5rem"},children:["(",t.latencyMs.toFixed(1)," ms)"]})]}),e.jsxs("div",{style:A.row,children:[e.jsx("span",{style:A.label,children:"Endpoint:"}),e.jsx("span",{style:A.value,children:t.url??e.jsx("span",{style:{color:"#888"},children:"built-in (no URL)"})})]}),t.error&&e.jsx("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:t.error})]})]})}function Te({title:t,children:r}){const[n,l]=s.useState(!0),a=`settings-${t.toLowerCase().replace(/[^a-z0-9]+/g,"-")}`;return e.jsxs("section",{className:"overflow-hidden rounded-xl border border-border bg-bg-elevated/40",children:[e.jsxs("button",{type:"button",onClick:()=>l(o=>!o),className:"flex w-full items-center justify-between rounded-t-xl bg-bg-elevated/60 px-4 py-3 text-left text-sm font-semibold text-foreground transition-colors hover:bg-bg-elevated","aria-expanded":n,"aria-controls":a,children:[e.jsx("span",{children:t}),e.jsx(le,{className:oe("h-4 w-4 text-muted-foreground transition-transform",n&&"rotate-180"),"aria-hidden":"true"})]}),n&&e.jsx("div",{id:a,className:"divide-y divide-border px-4 py-1",children:r})]})}const Re="rounded-md border border-border bg-bg-elevated/50 px-2 py-1 text-sm outline-none transition-colors focus:border-primary disabled:cursor-not-allowed disabled:opacity-50";function Me(){return e.jsx("span",{className:"ml-2 inline-flex items-center rounded-md border border-warning/40 bg-warning/15 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-warning",title:"Requires an LLM embedder (Ollama/HTTP) to be effective",children:"LLM"})}function Be({setting:t,id:r,llmActive:n,saving:l,onUpdate:a}){const[o,h]=s.useState(null),i=t.requiresLlm&&!n,m=s.useRef(null);s.useEffect(()=>()=>{m.current&&clearTimeout(m.current)},[]);const g=s.useCallback(c=>{a(t.key,c).then(u=>h(u)).catch(u=>h(u instanceof Error?u.message:String(u)))},[a,t.key]),d=s.useCallback(c=>{m.current&&clearTimeout(m.current),m.current=setTimeout(()=>g(c),500)},[g]),b=l||i;return e.jsxs("div",{className:"py-2.5",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center text-sm font-semibold text-foreground",children:[e.jsx("label",{htmlFor:`${r}-input`,className:"cursor-pointer",children:t.label}),t.requiresLlm&&!n&&e.jsx(Me,{})]}),e.jsx("div",{className:"mt-0.5 text-xs text-muted-foreground",children:t.description})]}),e.jsx("div",{className:"flex shrink-0 items-center gap-2",children:t.type==="boolean"?e.jsx(fe,{id:`${r}-input`,checked:!!t.value,disabled:b||i,onCheckedChange:c=>g(String(c)),"aria-label":t.label}):e.jsxs(e.Fragment,{children:[e.jsx("input",{id:`${r}-input`,type:t.type==="number"?"number":"text",defaultValue:String(t.value??""),min:t.min,max:t.max,disabled:b,onChange:c=>d(c.target.value),className:`${Re} ${t.type==="number"?"w-24":"w-56"}`}),t.unit&&e.jsx("span",{className:"text-xs text-muted-foreground",children:t.unit})]})})]}),o&&e.jsxs("p",{className:"mt-1 text-xs text-danger",children:["Error: ",o]})]})}function ze(){const[t,r]=s.useState(null),[n,l]=s.useState(null),[a,o]=s.useState(!1),[h,i]=s.useState(null),m=s.useCallback(()=>{ie().then(r).catch(d=>l(d instanceof Error?d.message:String(d)))},[]);s.useEffect(()=>{m()},[m]);const g=s.useCallback(async(d,b)=>{o(!0);try{const c=await ce({key:d,value:b});return i(c.restartRequired?"Saved — restart pi to apply changes.":"Saved."),m(),null}catch(c){return c instanceof Error?c.message:String(c)}finally{o(!1)}},[m]);return e.jsxs("div",{className:"flex flex-col gap-3",children:[n&&e.jsxs("p",{className:"text-sm text-danger",children:["Error: ",n]}),!t&&!n&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading settings..."}),t?.categories.map(d=>e.jsx(Te,{title:d.name,children:d.settings.map(b=>e.jsx(Be,{setting:b,id:`${d.name.replace(/[^a-z0-9]+/gi,"-")}-${b.key}`,llmActive:t.llmActive,saving:a,onUpdate:g},b.key))},d.name)),h&&e.jsx("div",{className:"mt-1 rounded-md border border-warning/40 bg-warning/10 p-2 text-xs text-warning",role:"status",children:h})]})}const f={container:{padding:"1rem",maxWidth:"720px",margin:"0 auto",fontFamily:"system-ui, sans-serif",color:"#e0e0e0"},section:{background:"#1a1a2e",borderRadius:"8px",padding:"1rem",marginBottom:"1rem",border:"1px solid #2a2a4e"},sectionTitle:{fontSize:"1.1rem",fontWeight:700,marginTop:0,marginBottom:"0.75rem",color:"#e0e0e0",borderBottom:"1px solid #333",paddingBottom:"0.5rem"},label:{fontWeight:600,color:"#a0a0c0",marginRight:"0.5rem"},value:{color:"#e0e0e0"},row:{marginBottom:"0.4rem",fontSize:"0.9rem"},warning:{background:"#3a2a00",border:"1px solid #665500",borderRadius:"8px",padding:"0.75rem",marginTop:"0.5rem",color:"#ffcc00",fontSize:"0.85rem"},badge:{display:"inline-block",padding:"0.15rem 0.5rem",borderRadius:"4px",fontSize:"0.8rem",fontWeight:600,marginLeft:"0.5rem"},detectRow:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"0.5rem 0",borderBottom:"1px solid #2a2a4e"},button:{background:"#3a5a9f",color:"#fff",border:"none",borderRadius:"6px",padding:"0.5rem 1rem",cursor:"pointer",fontSize:"0.9rem",fontWeight:600}},Ae="Saved; takes effect on next session start";function Ie({customUrl:t,setCustomUrl:r,applyEmbedder:n,configuring:l,inputEnabled:a,apiKeySet:o,embeddingDim:h,embeddingHeadersSet:i,allowRemoteEmbedder:m,configureResult:g,configureError:d}){const[b,c]=s.useState(""),[u,y]=s.useState(""),[v,w]=s.useState(!1),[C,p]=s.useState(""),[E,N]=s.useState(!1),[M,j]=s.useState(!1);return a&&!v&&typeof h=="string"&&(y(h),w(!0)),a&&!M&&typeof m=="boolean"&&(N(m),j(!0)),e.jsxs("div",{style:f.section,children:[e.jsx("h3",{style:f.sectionTitle,children:"Custom Endpoint (remote / third-party)"}),e.jsxs("p",{style:{fontSize:"0.85rem",color:"#a0a0c0",marginTop:0},children:["Point at any OpenAI-compatible embeddings API or hosted endpoint. This opts in to a non-loopback connection (sets"," ",e.jsx("code",{children:"MEGACOMPACT_ALLOW_REMOTE_EMBEDDER=1"}),") — your prompts' embedding requests will be sent to the URL you enter. Default is loopback-only."]}),e.jsxs("div",{style:{display:"flex",gap:"0.5rem",flexWrap:"wrap",alignItems:"center"},children:[e.jsx("input",{type:"url",placeholder:"https://api.example.com/v1/embeddings",value:t,onChange:x=>r(x.target.value),style:{flex:"1 1 300px",background:"#12122a",color:"#e0e0e0",border:"1px solid #2a2a4e",borderRadius:"6px",padding:"0.4rem 0.6rem",fontSize:"0.85rem",fontFamily:"monospace"}}),a&&e.jsx("input",{type:"password",autoComplete:"new-password","aria-label":"API key (optional Bearer)",placeholder:"API key (optional Bearer)",value:b,onChange:x=>c(x.target.value),style:{flex:"1 1 300px",background:"#12122a",color:"#e0e0e0",border:"1px solid #2a2a4e",borderRadius:"6px",padding:"0.4rem 0.6rem",fontSize:"0.85rem",fontFamily:"monospace"}}),a&&o&&e.jsx("span",{style:{fontSize:"0.75rem",color:"#81c784",border:"1px solid #2a4e2a",borderRadius:"4px",padding:"0.15rem 0.45rem"},children:"API key saved"}),a&&i&&e.jsx("span",{style:{fontSize:"0.75rem",color:"#81c784",border:"1px solid #2a4e2a",borderRadius:"4px",padding:"0.15rem 0.45rem"},children:"Headers saved"}),e.jsx("button",{style:{...f.button,opacity:t?1:.4},onClick:()=>n("custom",t,b,u,C,E),disabled:!t||l!==null,children:l==="custom"?"Writing...":"Use Custom URL"})]}),a&&e.jsxs("div",{style:{marginTop:"0.75rem"},children:[e.jsxs("div",{style:{marginBottom:"0.5rem"},children:[e.jsx("label",{style:{...f.label,display:"block",marginBottom:"0.25rem"},children:"Embedding dim (optional)"}),e.jsx("input",{type:"number",min:1,placeholder:"e.g. 384",value:u,onChange:x=>y(x.target.value),style:{width:"200px",background:"#12122a",color:"#e0e0e0",border:"1px solid #2a2a4e",borderRadius:"6px",padding:"0.4rem 0.6rem",fontSize:"0.85rem",fontFamily:"monospace"}})]}),e.jsxs("div",{style:{marginBottom:"0.5rem"},children:[e.jsx("label",{style:{...f.label,display:"block",marginBottom:"0.25rem"},children:"Embedding headers (JSON, write-only — never re-displayed)"}),e.jsx("textarea",{placeholder:'{"Authorization": "Bearer ..."}',value:C,onChange:x=>p(x.target.value),"aria-label":"Embedding headers JSON (write-only — never re-displayed)",rows:2,style:{width:"100%",background:"#12122a",color:"#e0e0e0",border:"1px solid #2a2a4e",borderRadius:"6px",padding:"0.4rem 0.6rem",fontSize:"0.85rem",fontFamily:"monospace",resize:"vertical"}})]}),e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:"0.5rem",fontSize:"0.85rem"},children:[e.jsx("input",{type:"checkbox",checked:E,onChange:x=>N(x.target.checked),"aria-label":"Allow remote embedder (skips loopback-only check)"}),"Allow remote embedder (skips loopback-only check)"]})]}),d!==null&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem",marginTop:"0.5rem"},children:["Configure error: ",d]}),g!==null&&g.embedder==="custom"&&e.jsx("div",{style:f.warning,children:Ae}),e.jsxs("div",{style:f.warning,children:[e.jsx("strong",{children:"Heads up:"})," a remote endpoint receives the text you embed (it does NOT receive your full conversation — only the strings passed to",e.jsx("code",{children:" embed()"})," for recall/dedup). Verify the endpoint's privacy policy before use."]})]})}function K(t){switch(t){case"trigram":return"TrigramEmbedder (heuristic, default)";case"http":return"HTTP Embedder (BYO localhost)";case"minilm":return"MiniLM (experimental)";default:return"Unknown"}}function Le(t){return t?.currentEmbedder!=="trigram"?null:e.jsxs("div",{style:f.warning,children:[e.jsx("strong",{children:"Note:"})," TrigramEmbedder is a heuristic-strength default embedder. It works without any setup but recall quality may be lower than a dedicated embedding backend. If you notice poor recall results, consider installing Ollama and running the"," ",e.jsx("code",{children:"/megasetup"})," command, or set"," ",e.jsx("code",{children:"MEGACOMPACT_EMBEDDING_URL"})," to point at your own localhost embedding server."]})}function q(t){const r=t?"#1a5a1a":"#3a1a1a",n=t?"#4caf50":"#f44336";return e.jsx("span",{style:{...f.badge,background:r,color:n},children:t?"Detected":"Not found"})}function Oe({status:t,statusError:r}){return e.jsxs("div",{style:f.section,children:[e.jsx("h3",{style:f.sectionTitle,children:"Current Embedder Configuration"}),r&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error: ",r]}),t&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:f.row,children:[e.jsx("span",{style:f.label,children:"Active Embedder:"}),e.jsx("span",{style:f.value,children:K(t.currentEmbedder)})]}),"configuredEmbedder"in t&&t.configuredEmbedder!==t.currentEmbedder&&e.jsxs("div",{style:f.warning,children:[e.jsx("strong",{children:"Configured but not active:"})," ",K(t.configuredEmbedder)," is configured in .mega-compact.env but not yet loaded."," ",e.jsx("strong",{children:"Restart pi"})," to activate it.",t.configuredUrl&&e.jsxs(e.Fragment,{children:[" (",t.configuredUrl,")"]})]}),"restartRequired"in t&&t.restartRequired&&e.jsxs("div",{style:{...f.row,color:"#ff9800"},children:[e.jsx("span",{style:f.label,children:"Status:"}),e.jsx("span",{style:f.value,children:"Restart required to activate the configured embedder"})]}),e.jsxs("div",{style:f.row,children:[e.jsx("span",{style:f.label,children:"Embedding URL:"}),e.jsx("span",{style:f.value,children:t.embeddingUrl??e.jsx("span",{style:{color:"#888"},children:"not set"})})]}),e.jsxs("div",{style:f.row,children:[e.jsx("span",{style:f.label,children:"Embed Cache:"}),e.jsx("span",{style:f.value,children:t.embedCache??e.jsx("span",{style:{color:"#888"},children:"not set"})})]}),e.jsxs("div",{style:f.row,children:[e.jsx("span",{style:f.label,children:"MiniLM:"}),e.jsx("span",{style:f.value,children:t.minilm?"enabled":"disabled"})]}),Le(t)]}),!t&&!r&&e.jsx("p",{style:{color:"#888",fontSize:"0.85rem"},children:"Loading configuration..."})]})}function Pe(){const[t,r]=s.useState(null),[n,l]=s.useState(null),[a,o]=s.useState(null),[h,i]=s.useState(null),[m,g]=s.useState(!1),[d,b]=s.useState(null),[c,u]=s.useState(null),[y,v]=s.useState(null),[w,C]=s.useState(""),[p,E]=s.useState(!1),N=s.useCallback(()=>{Z().then(r).catch(x=>o(x instanceof Error?x.message:String(x)))},[]),M=s.useCallback((x,T,B,U,W,P)=>{b(x),v(null),u(null);const I="embeddingHeadersSet"in(t??{});X({embedder:x,url:T,embeddingEndpointUrl:T,embeddingApiKey:B,...I?{embeddingDim:U,embeddingHeaders:W,allowRemoteEmbedder:P}:{}}).then(L=>{u(L),b(null),N()}).catch(L=>{v(L instanceof Error?L.message:String(L)),b(null)})},[N,t]),j=s.useCallback(()=>{g(!0),i(null),de().then(x=>{l(x),g(!1)}).catch(x=>{i(x instanceof Error?x.message:String(x)),g(!1)})},[]);return s.useEffect(()=>{N()},[N]),s.useEffect(()=>{p||t&&typeof t.embeddingEndpointUrl=="string"&&t.embeddingEndpointUrl.length>0&&(C(t.embeddingEndpointUrl),E(!0))},[t,p]),s.useEffect(()=>{const x=setInterval(N,5e3);return()=>clearInterval(x)},[N]),s.useEffect(()=>{j();const x=setInterval(j,5e3);return()=>clearInterval(x)},[j]),e.jsxs("div",{style:f.container,children:[e.jsx("h2",{style:{fontSize:"1.3rem",marginTop:0,marginBottom:"1rem"},children:"Embedder Setup"}),e.jsx(Ee,{}),e.jsx(Oe,{status:t,statusError:a}),e.jsxs("div",{style:f.section,children:[e.jsx("h3",{style:f.sectionTitle,children:"Local Embedder Detection"}),e.jsx("p",{style:{fontSize:"0.85rem",color:"#a0a0c0",marginTop:0},children:"Detect which local embedding backends are available on this machine. No software is installed — detection only."}),n&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:f.detectRow,children:[e.jsx("span",{children:e.jsx("strong",{children:"Ollama"})}),n.ollama!==null?e.jsxs("span",{children:[q(n.ollama.installed),n.ollama.installed&&e.jsx("span",{style:{fontSize:"0.8rem",color:"#a0a0c0",marginLeft:"0.5rem"},children:n.ollama.running?`server running, ${n.ollama.models.length} model(s)`:"server not running"})]}):e.jsx("span",{style:{color:"#888",fontSize:"0.85rem"},children:"not checked"})]}),e.jsxs("div",{style:f.detectRow,children:[e.jsx("span",{children:e.jsx("strong",{children:"llama.cpp"})}),n.llamaCpp!==null?e.jsxs("span",{children:[q(n.llamaCpp.installed),n.llamaCpp.installed&&n.llamaCpp.detail&&e.jsx("span",{style:{fontSize:"0.8rem",color:"#a0a0c0",marginLeft:"0.5rem"},children:n.llamaCpp.detail})]}):e.jsx("span",{style:{color:"#888",fontSize:"0.85rem"},children:"not checked"})]}),e.jsxs("div",{style:f.detectRow,children:[e.jsx("span",{children:e.jsx("strong",{children:"ONNX Runtime"})}),n.onnx!==null?e.jsxs("span",{children:[q(n.onnx.installed),n.onnx.installed&&n.onnx.detail&&e.jsx("span",{style:{fontSize:"0.8rem",color:"#a0a0c0",marginLeft:"0.5rem"},children:n.onnx.detail})]}):e.jsx("span",{style:{color:"#888",fontSize:"0.85rem"},children:"not checked"})]}),n.error&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.8rem",marginTop:"0.5rem"},children:["Detection error: ",n.error]})]}),h&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error: ",h]}),e.jsxs("div",{style:{marginTop:"1rem"},children:[e.jsx("button",{style:f.button,onClick:j,disabled:m,children:m?"Detecting...":"Run Detection"}),e.jsxs("span",{style:{fontSize:"0.8rem",color:"#888",marginLeft:"0.75rem"},children:["Or run ",e.jsx("code",{children:"/megasetup"})," in the chat for an interactive wizard."]})]}),n&&e.jsxs("div",{style:{marginTop:"1rem",paddingTop:"0.75rem",borderTop:"1px solid #2a2a4e"},children:[e.jsx("div",{style:{fontSize:"0.9rem",fontWeight:600,marginBottom:"0.5rem"},children:"Configure"}),e.jsxs("div",{style:{display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:[e.jsx("button",{style:{...f.button,opacity:n.ollama?.installed?1:.4},onClick:()=>M("ollama"),disabled:!n.ollama?.installed||d!==null,children:d==="ollama"?"Writing...":"Use Ollama"}),e.jsx("button",{style:{...f.button,opacity:n.llamaCpp?.installed?1:.4},onClick:()=>M("llama"),disabled:!n.llamaCpp?.installed||d!==null,children:d==="llama"?"Writing...":"Use llama.cpp"}),e.jsx("button",{style:{...f.button,opacity:n.onnx?.installed?1:.4},onClick:()=>M("onnx"),disabled:!n.onnx?.installed||d!==null,children:d==="onnx"?"Writing...":"Use ONNX"}),e.jsx("button",{style:{...f.button,background:"#444"},onClick:()=>M("trigram"),disabled:d!==null,children:d==="trigram"?"Writing...":"Use Trigram (default)"})]}),c&&c.embedder!=="custom"&&e.jsx("div",{style:f.warning,children:c.alreadyActive?"Already active — no restart needed.":`Configured ${c.embedder}. Restart pi to activate (config written to ${c.envPath}).`}),y&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem",marginTop:"0.5rem"},children:["Configure error: ",y]})]})]}),e.jsx(Ie,{customUrl:w,setCustomUrl:C,applyEmbedder:M,configuring:d,inputEnabled:t!==null&&"embeddingApiKeySet"in t,apiKeySet:t?.embeddingApiKeySet===!0,embeddingDim:t?.embeddingDim,embeddingHeadersSet:t?.embeddingHeadersSet===!0,allowRemoteEmbedder:t?.allowRemoteEmbedder,configureResult:c,configureError:y}),e.jsxs("div",{style:f.section,children:[e.jsx("h3",{style:f.sectionTitle,children:"How to Upgrade"}),e.jsxs("ul",{style:{fontSize:"0.85rem",lineHeight:1.6,paddingLeft:"1.25rem"},children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Ollama:"})," Install from"," ",e.jsx("a",{href:"https://ollama.com",style:{color:"#6a9fff"},target:"_blank",rel:"noopener noreferrer",children:"ollama.com"}),", then ",e.jsx("code",{children:"ollama pull nomic-embed-text"})," and restart pi. Set ",e.jsx("code",{children:"MEGACOMPACT_EMBEDDING_URL=http://localhost:11434/api/embeddings"}),"."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"llama.cpp:"})," Build or install llama.cpp, run"," ",e.jsx("code",{children:"llama-server"})," with an embedding model, and set the URL accordingly."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"ONNX Runtime:"})," Run a local text-embeddings server (e.g. TEI) and click ",e.jsx("strong",{children:"Use ONNX"})," above. Default URL: ",e.jsx("code",{children:"http://localhost:8081/v1/embeddings"}),"."]})]})]}),e.jsxs("div",{style:f.section,children:[e.jsx("h3",{style:f.sectionTitle,children:"Settings"}),e.jsx(ze,{})]})]})}function $(t){return t>=1e6?`${(t/1e6).toFixed(2)}M`:t>=1e3?`${Math.round(t/1e3)}K`:String(t)}function De(t,r,n){if(t<=0)return"—";const a=(r>0?r:Math.ceil(t*.1))+Math.ceil(t*(n/100)),o=t-a;return o<=0?"0 (at risk)":`${$(o)} tokens`}function J({label:t,value:r,min:n,max:l,step:a=1,onChange:o,warning:h}){return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between text-xs",children:[e.jsx("span",{className:"font-medium text-fg-muted",children:t}),e.jsxs("span",{className:`font-mono ${h?"text-warning":"text-fg"}`,title:h,children:[r,"%"]})]}),e.jsx("input",{type:"range",min:n,max:l,step:a,value:r,onChange:i=>o(Number(i.target.value)),className:"threshold-slider w-full"}),h&&e.jsxs("p",{className:"text-[10px] text-warning",children:["⚠ ",h]})]})}function _e({model:t,defaults:r,safetyRange:n,fireRange:l,onSave:a,onReset:o,saving:h}){const[i,m]=s.useState(t.threshold.safetyMarginPct),[g,d]=s.useState(t.threshold.firePointPct),[b,c]=s.useState(!1),[u,y]=s.useState(null);s.useEffect(()=>{m(t.threshold.safetyMarginPct),d(t.threshold.firePointPct),c(!1)},[t.threshold.safetyMarginPct,t.threshold.firePointPct]);const v=i<5?'Low safety margin — risks "conversation too long" errors when a single turn injects a large tool output between gate fires.':void 0,w=g>85?"High fire point — compaction may trigger close to the window cap; a single large turn can overshoot before the gate fires.":void 0,C=s.useCallback(async()=>{y(null);try{await a(t.modelId,i,g),c(!1)}catch(p){y(p instanceof Error?p.message:String(p))}},[t.modelId,i,g,a]);return e.jsxs("div",{className:"rounded-md border border-border bg-bg-elevated/30 p-3",children:[e.jsxs("div",{className:"mb-2 flex items-start justify-between",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm font-semibold text-fg",children:t.modelName??t.modelId}),t.threshold.isOverride&&e.jsx("span",{className:"rounded border border-primary/40 bg-primary/15 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-primary",title:"This model has a custom override (not the default)",children:"Override"})]}),e.jsxs("div",{className:"text-[11px] text-fg-muted",children:[t.provider," · ",$(t.contextWindow)," window ·"," ",$(t.maxTokens)," output"]})]}),e.jsxs("div",{className:"text-right text-[11px] text-fg-muted",children:[e.jsxs("div",{children:["Usable tail:"," ",e.jsx("span",{className:"font-mono text-fg",children:De(t.contextWindow,t.maxTokens,i)})]}),e.jsxs("div",{children:["Compaction fires at:"," ",e.jsx("span",{className:"font-mono text-fg",children:$(Math.ceil(t.contextWindow*(g/100)))})]})]})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2",children:[e.jsx(J,{label:"Safety margin",value:i,min:n[0],max:n[1],onChange:p=>{m(p),c(!0)},warning:v}),e.jsx(J,{label:"Fire point",value:g,min:l[0],max:l[1],onChange:p=>{d(p),c(!0)},warning:w})]}),e.jsxs("div",{className:"mt-2 flex items-center gap-2",children:[e.jsx("button",{type:"button",onClick:C,disabled:!b||h,className:"rounded-md bg-primary px-2.5 py-1 text-xs font-semibold text-primary-fg disabled:cursor-not-allowed disabled:opacity-50",children:b?"Save override":"Saved"}),t.threshold.isOverride&&e.jsxs("button",{type:"button",onClick:()=>o(t.modelId),disabled:h,className:"rounded-md border border-border px-2.5 py-1 text-xs text-fg-muted disabled:cursor-not-allowed disabled:opacity-50",children:["Reset to default (",r.safetyMarginPct,"% /"," ",r.firePointPct,"%)"]}),u&&e.jsx("span",{className:"text-[11px] text-error",children:u})]})]})}function $e(){const[t,r]=s.useState(null),[n,l]=s.useState(!0),[a,o]=s.useState(null),[h,i]=s.useState(!1),m=s.useCallback(async()=>{try{o(null),r(await ge())}catch(b){o(b instanceof Error?b.message:String(b))}finally{l(!1)}},[]);s.useEffect(()=>{m()},[m]);const g=s.useCallback(async(b,c,u)=>{i(!0);try{await pe({modelId:b,safetyMarginPct:c,firePointPct:u}),await m()}finally{i(!1)}},[m]),d=s.useCallback(async b=>{i(!0);try{await xe(b),await m()}finally{i(!1)}},[m]);return n?e.jsx("div",{className:"p-4 text-sm text-fg-muted",children:"Loading thresholds…"}):a?e.jsxs("div",{className:"p-4 text-sm text-error",children:["Error: ",a]}):t?e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{className:"rounded-md border border-border bg-bg-elevated/20 p-3",children:[e.jsx("h3",{className:"text-sm font-semibold",children:"Per-Model Compaction Thresholds"}),e.jsxs("p",{className:"mt-1 text-[11px] text-fg-muted",children:["Tune when compaction fires + how much safety margin to reserve,",e.jsx("strong",{children:" per model"}),". Different providers' models range from 8K to 1M+ context — one global % is wrong. Defaults:"," ",e.jsxs("span",{className:"font-mono",children:[t.defaults.safetyMarginPct,"% safety"]})," ","/"," ",e.jsxs("span",{className:"font-mono",children:[t.defaults.firePointPct,"% fire"]}),". Values outside the safe band show warnings."]})]}),t.models.length===0?e.jsx("div",{className:"rounded-md border border-border p-4 text-sm text-fg-muted",children:"No models captured yet. Start a pi session in any repo to populate model snapshots, then return here to tune per-model thresholds."}):e.jsx("div",{className:"flex flex-col gap-3",children:t.models.map(b=>e.jsx(_e,{model:b,defaults:t.defaults,safetyRange:t.defaults.safetyMarginRange,fireRange:t.defaults.firePointRange,onSave:g,onReset:d,saving:h},b.modelId))})]}):e.jsx("div",{className:"p-4 text-sm text-fg-muted",children:"No data."})}async function Ue(){const t=await fetch("/api/setup-cortex-status");if(!t.ok)throw new Error(`setup-cortex status: ${t.status}`);return t.json()}async function We(t){const r=await fetch("/api/setup-cortex-action",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(r.ok)return{ok:!0,result:await r.json()};let n;try{n=await r.json()}catch{n={error:"disabled"}}return{ok:!1,status:r.status,error:n}}async function Fe(t){const r=await fetch(`/api/setup-cortex-action-log?name=${encodeURIComponent(t)}`);if(!r.ok)throw new Error(`setup-cortex action-log: ${r.status}`);return r.json()}function He(t){return t===null?!0:t.enabled&&t.status!=="off"}function se(){const[t,r]=s.useState({loading:!0,error:null,data:null}),n=s.useCallback(()=>{r(l=>({...l,loading:!0})),Ue().then(l=>r(a=>({...a,data:l,loading:!1,error:null}))).catch(l=>r(a=>({...a,loading:!1,error:l instanceof Error?l.message:String(l)})))},[]);return s.useEffect(()=>{n();const l=setInterval(n,5e3);return()=>clearInterval(l)},[n]),[t,n]}const S={container:{padding:"1rem",maxWidth:"720px",margin:"0 auto",fontFamily:"system-ui, sans-serif",color:"#e0e0e0"},section:{background:"#1a1a2e",borderRadius:"8px",padding:"1rem",marginBottom:"1rem",border:"1px solid #2a2a4e"},sectionTitle:{fontSize:"1.1rem",fontWeight:700,marginTop:0,marginBottom:"0.75rem",color:"#e0e0e0",borderBottom:"1px solid #333",paddingBottom:"0.5rem"},label:{fontWeight:600,color:"#a0a0c0",marginRight:"0.5rem"},value:{color:"#e0e0e0"},row:{marginBottom:"0.4rem",fontSize:"0.9rem"},warning:{background:"#3a2a00",border:"1px solid #665500",borderRadius:"8px",padding:"0.75rem",marginTop:"0.5rem",color:"#ffcc00",fontSize:"0.85rem"},blocked:{background:"#3a1a1a",border:"1px solid #662222",borderRadius:"8px",padding:"0.75rem",marginTop:"0.5rem",color:"#ff6666",fontSize:"0.85rem"},badge:{display:"inline-block",padding:"0.15rem 0.5rem",borderRadius:"4px",fontSize:"0.8rem",fontWeight:600,marginLeft:"0.5rem"},button:{background:"#3a5a9f",color:"#fff",border:"none",borderRadius:"6px",padding:"0.5rem 1rem",cursor:"pointer",fontSize:"0.9rem",fontWeight:600},buttonDanger:{background:"#6a2a2a",color:"#ffb3b3",border:"1px solid #662222",borderRadius:"6px",padding:"0.5rem 1rem",cursor:"pointer",fontSize:"0.9rem",fontWeight:600},blockerRow:{display:"flex",justifyContent:"space-between",alignItems:"center",gap:"0.5rem",padding:"0.5rem 0.6rem",borderRadius:"6px",marginBottom:"0.35rem",fontSize:"0.85rem"},blockerRowHighlighted:{background:"#3a1a1a",border:"1px solid #662222"},mono:{fontFamily:"ui-monospace, monospace",fontSize:"0.8rem"}};function Ge(t){switch(t){case"A":return"A — qualified learned encoder asset";case"B":return"B — demoted (heuristic/trigram)";case"C":return"C — absent (asset not verified)";default:return"—"}}function qe(t){const r=t==="qualified"?"#1a5a1a":t==="demoted"?"#3a3a1a":"#3a1a1a",n=t==="qualified"?"#4caf50":t==="demoted"?"#ffcc00":"#f44336";return e.jsx("span",{style:{...S.badge,background:r,color:n},children:t??"unknown"})}function Ve({data:t,error:r}){return e.jsxs("div",{style:S.section,children:[e.jsxs("h3",{style:S.sectionTitle,children:[e.jsx("span",{style:{marginRight:"0.5rem"},children:"Cortex Encoder"}),e.jsx(be,{status:t?.status})]}),r&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error: ",r]}),!t&&!r&&e.jsx("p",{style:{color:"#888",fontSize:"0.85rem"},children:"Loading cortex status..."}),!t?.enabled&&e.jsx("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:"Cortex status disabled (VC9A off)."}),e.jsxs("div",{style:S.row,children:[e.jsx("span",{style:S.label,children:"Mode:"}),e.jsx("span",{style:S.value,children:Ge(t?.encoderHealth.mode)})]}),e.jsxs("div",{style:S.row,children:[e.jsx("span",{style:S.label,children:"Asset digest prefix:"}),e.jsx("span",{style:{...S.value,...S.mono},children:t?.assetDigestPrefix??e.jsx("span",{style:{color:"#888"},children:"not available"})})]}),e.jsxs("div",{style:S.row,children:[e.jsx("span",{style:S.label,children:"Qualification:"}),qe(t?.qualification.verdict)]}),(t?.qualification.thresholdFailures.length??0)>0&&e.jsxs("div",{style:S.warning,children:[e.jsx("strong",{children:"Threshold failure(s):"})," ",t?.qualification.thresholdFailures.join(", ")]}),t?.status==="awaiting_data"&&e.jsx("p",{style:{color:"#a0a0c0",fontSize:"0.85rem"},children:"Awaiting encoder data. Qualification will appear once an asset is present."}),t?.status==="deferred"&&e.jsx("p",{style:{color:"#a0a0c0",fontSize:"0.85rem"},children:"Encoder status deferred."})]})}function Xe(t){switch(t){case"blocker":return"#f44336";case"high":return"#ff9800";default:return"#a0a0c0"}}function Ke({blockers:t,highlight:r,darwinX64:n}){const l=r??[];return e.jsxs("div",{style:S.section,children:[e.jsxs("h3",{style:S.sectionTitle,children:["Open Hard-Gate Blockers",e.jsx("span",{style:{...S.badge,background:"#3a1a1a",color:"#f44336"},children:t.length})]}),t.length===0&&e.jsx("p",{style:{color:"#4caf50",fontSize:"0.85rem"},children:"No open hard-gate blockers."}),n?.demoted===!0&&e.jsxs("div",{style:S.blockerRow,"data-darwin-x64-demoted":"true",children:[e.jsx("span",{style:{...S.mono,fontWeight:700},children:"HG-4"}),e.jsx("span",{style:{flex:1,color:"#e0e0e0"},children:n.reason||"darwin-x64: demoted to WASM (reason unavailable)"}),e.jsx("span",{style:{color:"#ff9800"},children:"high"}),e.jsx("span",{style:{color:"#4caf50",fontStyle:"italic"},children:"diagnosed"})]}),t.map(a=>{const o=l.includes(a.id);return e.jsxs("div",{style:{...S.blockerRow,...o?S.blockerRowHighlighted:{}},children:[e.jsx("span",{style:{...S.mono,fontWeight:700},children:a.id}),e.jsx("span",{style:{flex:1,color:"#e0e0e0"},children:a.title}),e.jsx("span",{style:{color:Xe(a.severity)},children:a.severity}),e.jsx("span",{style:{color:"#a0a0c0",fontStyle:"italic"},children:o?"gates this action":a.status})]},a.id)}),l.length>0&&e.jsxs("div",{style:S.blocked,children:[e.jsx("strong",{children:"Blocked:"})," the requested action is gated by the highlighted open hard-gate item(s). It was not run."]})]})}const Je=[{key:"fetch-model",label:"Fetch Model",desc:"Fetch the qualified encoder model asset",dangerous:!0,confirm:"Fetch the encoder model asset onto this host? (Gated by any open hard gate.)"},{key:"bench",label:"Bench Encoder",desc:"Benchmark the encoder runtime on this host",dangerous:!0,confirm:"Run an encoder benchmark on this host? (Gated by any open hard gate.)"},{key:"verify-asset",label:"Verify Asset",desc:"Re-verify the committed encoder asset",dangerous:!1,confirm:"Re-verify the committed encoder asset?"}];function Qe({data:t,onBlocked:r,onAction:n}){const[l,a]=s.useState(null),[o,h]=s.useState(null),[i,m]=s.useState(null),[g,d]=s.useState(!1),b=s.useCallback(async u=>{a(u.key),m(null),h(null),d(!1),r([]);try{const y=await We({action:u.key,confirm:!0});if(y.ok){const v=y.result;let w=null,C=null;try{const p=await Fe(v.logName);w=p.tail,C=p.complete}catch{}h({action:v.action,logName:v.logName,tail:w,complete:C,message:v.ok?`${v.action} completed (spawned: ${v.spawned})`:`${v.action} did not complete cleanly`}),n()}else y.error.error==="action_blocked_by_open_item"?(r(y.error.blockers),m("The action is blocked by an open hard-gate item and was not run.")):y.error.error==="confirmation_required"?m("The server rejected the action: explicit confirmation is required."):(d(!0),m(y.status===404?"Setup Cortex actions are disabled (off).":`Action failed (${y.status}).`))}catch(y){m(y instanceof Error?y.message:String(y))}finally{a(null)}},[r,n]),c=u=>{window.confirm(u.confirm)&&b(u)};return e.jsxs("div",{style:S.section,children:[e.jsx("h3",{style:S.sectionTitle,children:"Cortex Actions"}),Je.map(u=>{const y=l===u.key;return e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"0.5rem",padding:"0.5rem 0",borderBottom:"1px solid #2a2a4e"},children:[e.jsxs("div",{children:[e.jsx("div",{style:{fontWeight:600},children:u.label}),e.jsx("div",{style:{fontSize:"0.8rem",color:"#a0a0c0"},children:u.desc})]}),e.jsx("button",{style:u.dangerous?S.buttonDanger:S.button,disabled:l!==null,onClick:()=>c(u),children:y?"Running…":"Run"})]},u.key)}),g&&e.jsx("div",{style:S.blocked,children:"Setup Cortex actions are disabled. Enable MEGACOMPACT_VC9B to run them."}),i&&!g&&e.jsx("p",{style:{color:"#f44336",fontSize:"0.85rem",marginTop:"0.5rem"},children:i}),o&&e.jsxs("div",{style:S.warning,"data-testid":"cortex-action-result",children:[e.jsxs("strong",{children:["Result (",o.action,"):"]})," ",o.message,o.logName&&e.jsxs("span",{style:{...S.mono,marginLeft:"0.5rem"},children:["log: ",o.logName]}),o.tail!==null&&e.jsxs("pre",{style:{whiteSpace:"pre-wrap",wordBreak:"break-word",fontSize:"0.75rem",maxHeight:"12rem",overflow:"auto",marginTop:"0.5rem"},children:[o.tail,o.complete===!1&&`
2
- … (truncated)`]})]}),!t?.enabled&&!g&&e.jsx("p",{style:{color:"#a0a0c0",fontSize:"0.8rem",marginTop:"0.5rem"},children:"Cortex status unavailable — actions may not be schedulable."})]})}const R={section:{background:"#1a1a2e",borderRadius:"8px",padding:"1rem",marginBottom:"1rem",border:"1px solid #2a2a4e"},sectionTitle:{fontSize:"1.1rem",fontWeight:700,marginTop:0,marginBottom:"0.25rem",color:"#e0e0e0"},subtitle:{fontSize:"0.85rem",color:"#a0a0c0",marginTop:0,marginBottom:"0.75rem"},row:{marginBottom:"0.4rem",fontSize:"0.9rem"},label:{fontWeight:600,color:"#a0a0c0",marginRight:"0.5rem"},value:{color:"#e0e0e0"},warning:{background:"#3a2a00",border:"1px solid #665500",borderRadius:"8px",padding:"0.75rem",marginTop:"0.5rem",color:"#ffcc00",fontSize:"0.85rem"},toggleRow:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.75rem",fontSize:"0.9rem"}},V=8192;function Ye(){const[t,r]=s.useState(null),[n,l]=s.useState(null),[a,o]=s.useState(!1),[h,i]=s.useState(""),[m,g]=s.useState(!1),d=s.useCallback(()=>{Z().then(r).catch(p=>l(p instanceof Error?p.message:String(p)))},[]);s.useEffect(()=>{d()},[d]),s.useEffect(()=>{const p=setInterval(d,5e3);return()=>clearInterval(p)},[d]);const b=t!==null&&"encoderNativeOptIn"in t,c=t?.nativeOrtBudgetEffectiveMib;s.useEffect(()=>{if(!m&&t&&"nativeOrtBudgetEffectiveMib"in t){const p=t.nativeOrtBudgetMib??t.nativeOrtBudgetEffectiveMib??"";typeof p=="string"&&i(p),g(!0)}},[m,t]);const u=s.useCallback(p=>{o(!0),l(null),X({embedder:"custom",url:t?.embeddingEndpointUrl??void 0,encoderNativeOptIn:p}).then(()=>{o(!1),d()}).catch(E=>{l(E instanceof Error?E.message:String(E)),o(!1)})},[t,d]),y=s.useCallback(()=>{const p=h.trim();if(!/^\d+$/.test(p)){l("Install budget must be a positive integer (MiB)");return}const E=Number(p);if(!Number.isSafeInteger(E)||E<1||E>V){l(`Install budget must be between 1 and ${V} MiB`);return}o(!0),l(null),X({embedder:"custom",url:t?.embeddingEndpointUrl??void 0,nativeOrtBudgetMib:p}).then(()=>{o(!1),d()}).catch(N=>{l(N instanceof Error?N.message:String(N)),o(!1)})},[h,t,d]);if(!b)return e.jsx(e.Fragment,{});const v=t?.encoderBackend??"wasm",w=t?.encoderDemotionReason??null,C=t!==null&&"nativeOrtBudgetEffectiveMib"in t;return e.jsxs("div",{style:R.section,children:[e.jsx("h3",{style:R.sectionTitle,children:"Encoder Runtime"}),e.jsx("p",{style:R.subtitle,children:"ONNX backend selection"}),e.jsxs("div",{style:R.toggleRow,children:[e.jsx("input",{type:"checkbox",checked:t?.encoderNativeOptIn===!0,onChange:p=>u(p.target.checked),disabled:a,"aria-label":"Native ONNX runtime (onnxruntime-node)"}),e.jsx("label",{children:"Native ONNX runtime (onnxruntime-node)"}),a&&e.jsx("span",{style:{fontSize:"0.8rem",color:"#a0a0c0"},children:"saving..."})]}),e.jsxs("div",{style:R.row,children:[e.jsx("span",{style:R.label,children:"Effective backend:"}),e.jsx("span",{style:R.value,children:v})]}),C&&e.jsxs("div",{style:R.row,children:[e.jsx("label",{htmlFor:"enc2-budget-input",style:{...R.label,marginRight:"0.5rem"},children:"Native install budget (MiB):"}),e.jsx("input",{id:"enc2-budget-input",type:"number",min:1,max:V,step:1,value:h,onChange:p=>i(p.target.value),disabled:a,style:{width:"6rem"},"aria-label":"Native onnxruntime install budget in MiB"}),e.jsx("button",{type:"button",onClick:y,disabled:a||h.trim().length===0,style:{marginLeft:"0.5rem"},children:"Save"}),c!==void 0&&e.jsxs("span",{style:{...R.value,marginLeft:"0.5rem"},children:["(effective: ",c," MiB)"]})]}),w!==null&&e.jsxs("div",{style:R.warning,children:[e.jsx("strong",{children:"Demoted:"})," ",w]}),n&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error: ",n]})]})}const k={section:{background:"#1a1a2e",borderRadius:"8px",padding:"1rem",marginBottom:"1rem",border:"1px solid #2a2a4e"},sectionTitle:{fontSize:"1.1rem",fontWeight:700,marginTop:0,marginBottom:"0.25rem",color:"#e0e0e0"},subtitle:{fontSize:"0.85rem",color:"#a0a0c0",marginTop:0,marginBottom:"0.75rem"},row:{marginBottom:"0.4rem",fontSize:"0.9rem"},label:{fontWeight:600,color:"#a0a0c0",marginRight:"0.5rem"},value:{color:"#e0e0e0"},disabled:{background:"#1a1a2e",border:"1px solid #2a2a4e",borderRadius:"8px",padding:"1rem",marginBottom:"1rem",color:"#a0a0c0",fontSize:"0.85rem"}},Ze=()=>{const{data:t,error:r,loading:n}=me(s.useMemo(()=>()=>ue("/api/cosine-fp-report").catch(l=>{if(l instanceof he&&l.status===404)return null;throw l}),[]),{pollInterval:5e3});return t===null&&!r&&!n?e.jsx("div",{style:k.disabled,children:"Cosine FP synthetic bench: disabled (MEGACOMPACT_COSINE_FP_BENCH=0)."}):e.jsxs("div",{style:k.section,children:[e.jsx("h3",{style:k.sectionTitle,children:"Cosine FP threshold"}),e.jsx("p",{style:k.subtitle,children:"Last synthetic bench threshold recommendation"}),r!==null?e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error loading report: ",r.message]}):t===null?e.jsx("div",{style:k.value,children:"Loading…"}):e.jsxs("div",{children:[e.jsxs("div",{style:k.row,children:[e.jsx("span",{style:k.label,children:"Recommended default:"}),e.jsxs("span",{style:k.value,children:[t.recommendedDefault??"—"," (shipped"," ",t.shippedDefault,")"]})]}),e.jsxs("div",{style:k.row,children:[e.jsx("span",{style:k.label,children:"Overrides:"}),e.jsxs("span",{style:k.value,children:["CODE ",t.overrides?.code??"—"," · PROSE"," ",t.overrides?.prose??"—"," · MIXED"," ",t.overrides?.mixed??"—"]})]}),e.jsxs("div",{style:k.row,children:[e.jsx("span",{style:k.label,children:"Grid:"}),e.jsx("span",{style:k.value,children:t.grid?`${t.grid.lo} → ${t.grid.hi} (${t.grid.points} points)`:"—"})]}),e.jsxs("div",{style:k.row,children:[e.jsx("span",{style:k.label,children:"Report digest:"}),e.jsx("span",{style:k.value,title:t.digest??void 0,children:t.digest?t.digest.slice(0,16)+"…":"—"})]})]})]})};function et(){const[t,r]=se(),[n,l]=s.useState([]),a=s.useCallback(h=>{l(h)},[]),o=s.useCallback(()=>{r()},[r]);return e.jsxs("div",{style:S.container,children:[e.jsx("h2",{style:{fontSize:"1.3rem",marginTop:0,marginBottom:"1rem"},children:"Setup Cortex"}),e.jsx("p",{style:{fontSize:"0.85rem",color:"#a0a0c0",marginTop:0},children:"Vector-cortex encoder gate: mode, qualification, open hard-gate blockers, and the confirmation-gated fetch/bench/verify actions."}),e.jsx(Ve,{data:t.data,error:t.error}),e.jsx(Ye,{}),e.jsx(Ze,{}),e.jsx(Ke,{blockers:t.data?.blockers??[],highlight:n,darwinX64:t.data?.darwinX64}),e.jsx(Qe,{data:t.data,onBlocked:a,onAction:o})]})}const tt=[{id:"embedder",label:"Embedder"},{id:"thresholds",label:"Thresholds"},{id:"config",label:"Config"},{id:"game",label:"Game Mode"},{id:"achievements",label:"Achievements"}],st={id:"cortex",label:"Cortex"};function it(){const[t,r]=s.useState("embedder"),[n]=se(),l=s.useMemo(()=>{const a=[...tt];return He(n.data)&&a.push(st),a},[n.data]);return e.jsxs("div",{className:"mx-auto flex max-w-3xl flex-col gap-4 p-4",children:[e.jsx("nav",{className:"flex gap-2 border-b border-border pb-2","aria-label":"Setup sections",children:l.map(a=>e.jsx(ye,{pressed:t===a.id,onClick:()=>r(a.id),children:a.label},a.id))}),t==="embedder"&&e.jsx(Pe,{}),t==="thresholds"&&e.jsx($e,{}),t==="config"&&e.jsx(Ne,{}),t==="game"&&e.jsx(Se,{}),t==="achievements"&&e.jsx(we,{}),t==="cortex"&&e.jsx(et,{})]})}export{it as default};
3
- //# sourceMappingURL=SetupTab-C6b8YuBK.js.map