prism-mcp-server 20.21.20 → 20.21.21
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.
- package/README.md +7 -0
- package/dist/dashboard/ledgerReader.js +4 -2
- package/dist/dashboard/readMessages.js +48 -0
- package/dist/dashboard/server.js +13 -10
- package/dist/dashboard/ui.js +231 -386
- package/dist/storage/portalContracts.js +23 -0
- package/dist/storage/sqlite.js +7 -4
- package/dist/storage/supabase.js +32 -24
- package/dist/storage/synalux.js +14 -1
- package/dist/tools/hygieneHandlers.js +7 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -158,6 +158,13 @@ or by re-enabling after each run.
|
|
|
158
158
|
<details>
|
|
159
159
|
<summary>Release history (optional)</summary>
|
|
160
160
|
|
|
161
|
+
## What's New in v20.21.21
|
|
162
|
+
|
|
163
|
+
- Prism Dashboard now reports unavailable analytics and factory reads clearly,
|
|
164
|
+
prevents stale project results, and keeps graph filters and counts in sync.
|
|
165
|
+
- Project analytics can be read through the authenticated Portal API with
|
|
166
|
+
validated 14-day activity data.
|
|
167
|
+
|
|
161
168
|
## What's New in v20.21.20
|
|
162
169
|
|
|
163
170
|
- Fixed: a `session_save_ledger` call refused with `context_not_loaded`, or the
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { PRISM_USER_ID } from '../config.js';
|
|
1
2
|
/** Paid clients have Portal credentials, not direct Supabase credentials. */
|
|
2
|
-
export async function readDashboardLedger(storage, backend, project, order, limit) {
|
|
3
|
+
export async function readDashboardLedger(storage, backend, project, order, limit, userId = PRISM_USER_ID) {
|
|
3
4
|
if (backend !== "synalux") {
|
|
4
|
-
return storage.getLedgerEntries({ project: `eq.${project}`,
|
|
5
|
+
return storage.getLedgerEntries({ project: `eq.${project}`, user_id: `eq.${userId}`,
|
|
6
|
+
deleted_at: 'is.null', order, limit: String(limit) });
|
|
5
7
|
}
|
|
6
8
|
if (!storage.getDashboardLedger)
|
|
7
9
|
throw new Error("Cloud dashboard ledger reader unavailable");
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const DASHBOARD_READ_MESSAGES = {
|
|
2
|
+
analyticsLoading: 'Loading memory analytics…',
|
|
3
|
+
analyticsUnavailable: 'Memory analytics unavailable. Retry to refresh this project.',
|
|
4
|
+
pipelinesLoading: 'Loading pipelines…',
|
|
5
|
+
pipelinesUnavailable: 'Pipelines unavailable. Retry to refresh the list.',
|
|
6
|
+
retry: 'Retry',
|
|
7
|
+
activeEntries: 'Active entries',
|
|
8
|
+
consolidatedEntries: 'Entries consolidated',
|
|
9
|
+
sessionEntry: 'session', rollupEntry: 'rollup',
|
|
10
|
+
projectUnavailable: 'Project data unavailable. Retry Inspect to refresh.',
|
|
11
|
+
graphLoading: 'Loading graph…',
|
|
12
|
+
graphUnavailable: 'Graph unavailable. Retry to refresh the selected filters.',
|
|
13
|
+
graphEmpty: 'No knowledge associations match these filters.',
|
|
14
|
+
graphSessions: 'sessions', graphStoredLinks: 'stored links',
|
|
15
|
+
graphProjects: 'projects', graphKeywords: 'keywords', graphEdges: 'edges',
|
|
16
|
+
vmUnavailable: 'VM inventory unavailable. This dashboard has not loaded a live template or running-instance source.',
|
|
17
|
+
vmActionUnavailable: 'VM creation is unavailable until a runtime provider is connected to this dashboard.',
|
|
18
|
+
marketplaceUnavailable: 'Component catalog unavailable. Product availability, prices and payouts have not been loaded from a live source.',
|
|
19
|
+
marketplaceActionUnavailable: 'This action is unavailable until a live component catalog is connected.',
|
|
20
|
+
complianceUnavailable: 'Live enforcement status unavailable in this dashboard. No control can be certified active from this view.',
|
|
21
|
+
auditUnavailable: 'Audit events unavailable. This dashboard has not loaded a live audit source.',
|
|
22
|
+
policyUnavailable: 'This dashboard has not loaded a verified policy reference.',
|
|
23
|
+
directGeminiKey: 'Used for direct Gemini operations. Synalux-managed Gemini embeddings use your account instead of a separate Google key.',
|
|
24
|
+
providerChoice: 'Text generation and semantic retrieval use separate provider settings. Choose the providers that match your configured services.',
|
|
25
|
+
customRoleInstructions: 'Custom role instructions are injected when context loads for this role. This editor does not list the provisioned skill library.',
|
|
26
|
+
vmTitle: 'VM Lab 🖥️', vmAvailability: 'Check VM availability',
|
|
27
|
+
marketplaceTitle: 'Component Marketplace 🛒', marketplaceAvailability: 'Check catalog availability',
|
|
28
|
+
publishComponent: 'Publish Component', complianceTitle: 'Compliance status 🛡️',
|
|
29
|
+
policyAvailability: 'Check policy reference',
|
|
30
|
+
memoryScanTitle: 'Memory scan 🩺', refreshScan: 'Refresh scan',
|
|
31
|
+
scanLoading: 'Scanning…', coverageUnavailable: 'Scan coverage unavailable. Refresh to try again.',
|
|
32
|
+
scanUnavailable: 'Scan unavailable. No integrity result can be confirmed.',
|
|
33
|
+
partialScan: 'Partial inventory', scanPassed: 'Scan passed',
|
|
34
|
+
partialCoverage: 'Account-wide embedding inventory only. Duplicate, orphan and rollup checks are not measured by this cloud view.',
|
|
35
|
+
backendCoverage: 'Account-wide memory scan. This result does not describe overall service health.',
|
|
36
|
+
noScanIssues: 'No issues reported by this scan.',
|
|
37
|
+
noEmbeddingIssues: 'No missing embeddings reported. Other integrity checks are not measured here.',
|
|
38
|
+
scanIssues: 'Issues reported',
|
|
39
|
+
repairCoverage: 'Fix Issues is available for missing embeddings or orphaned handoffs. Cleanup repairs embeddings and removes orphaned handoffs. Other failures require their own recovery path.',
|
|
40
|
+
graphActivityTitle: 'Graph activity · this process', recordedSuccess: 'Recorded synthesis success',
|
|
41
|
+
schedulerOutcome: 'Latest scheduler graph synthesis', recordedResults: 'Recorded results',
|
|
42
|
+
schedulerSucceeded: 'succeeded', schedulerFailed: 'failed', schedulerAttempted: 'attempted',
|
|
43
|
+
lastDirectLinks: 'Last direct synthesis links', lastPrune: 'Last pruning ratio',
|
|
44
|
+
};
|
|
45
|
+
export const ANALYTICS_METRIC_IDS = [
|
|
46
|
+
'astat-entries', 'astat-rollups', 'astat-savings', 'astat-avglen',
|
|
47
|
+
];
|
|
48
|
+
export const ANALYTICS_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
package/dist/dashboard/server.js
CHANGED
|
@@ -37,6 +37,7 @@ import { redactSettings } from "../tools/commonHelpers.js";
|
|
|
37
37
|
import { handleGraphRoutes } from "./graphRouter.js";
|
|
38
38
|
import { handleAccountRoutes } from "./accountRouter.js";
|
|
39
39
|
import { createDashboardStorageAccessor } from "./storageAccessor.js";
|
|
40
|
+
import { DASHBOARD_READ_MESSAGES } from "./readMessages.js";
|
|
40
41
|
import { isDashboardSettingKeyAllowed, isDashboardSettingValueAllowed } from "./settingsPolicy.js";
|
|
41
42
|
import { isTrustedRequest, isRebindGuardedPath } from "./hostGuard.js";
|
|
42
43
|
import { resolveDashboardToken, requestHasToken, buildTokenCookie, dashboardTokenCookieName, isDashboardTokenProtectedPath, } from "./dashboardToken.js";
|
|
@@ -352,7 +353,7 @@ return false;}
|
|
|
352
353
|
googleApiKey: {
|
|
353
354
|
type: "string",
|
|
354
355
|
title: "Google AI API Key",
|
|
355
|
-
description:
|
|
356
|
+
description: DASHBOARD_READ_MESSAGES.directGeminiKey,
|
|
356
357
|
},
|
|
357
358
|
storage: {
|
|
358
359
|
type: "string",
|
|
@@ -553,18 +554,19 @@ return false;}
|
|
|
553
554
|
}
|
|
554
555
|
const stats = await s.getHealthStats(PRISM_USER_ID);
|
|
555
556
|
const report = runHealthCheck(stats);
|
|
556
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
557
|
-
return res.end(JSON.stringify(report
|
|
557
|
+
res.writeHead(stats.missingEmbeddings < 0 ? 503 : 200, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
558
|
+
return res.end(JSON.stringify({ ...report, scope: 'account', backend: activeStorageBackend,
|
|
559
|
+
coverage: stats.missingEmbeddings < 0 ? 'unavailable' : activeStorageBackend === 'synalux' ? 'embedding_inventory' : 'backend_scan' }));
|
|
558
560
|
}
|
|
559
561
|
catch (err) {
|
|
560
562
|
console.error("[Dashboard] Health check error:", err);
|
|
561
|
-
res.writeHead(
|
|
563
|
+
res.writeHead(503, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
562
564
|
return res.end(JSON.stringify({
|
|
563
565
|
status: "unknown",
|
|
566
|
+
scope: 'account', backend: activeStorageBackend, coverage: 'unavailable',
|
|
564
567
|
summary: "Health check unavailable",
|
|
565
568
|
issues: [],
|
|
566
569
|
counts: { errors: 0, warnings: 0, infos: 0 },
|
|
567
|
-
totals: { activeEntries: 0, handoffs: 0, rollups: 0 },
|
|
568
570
|
timestamp: new Date().toISOString(),
|
|
569
571
|
}));
|
|
570
572
|
}
|
|
@@ -581,6 +583,10 @@ return false;}
|
|
|
581
583
|
}
|
|
582
584
|
const stats = await s.getHealthStats(PRISM_USER_ID);
|
|
583
585
|
const report = runHealthCheck(stats);
|
|
586
|
+
if (stats.missingEmbeddings < 0) {
|
|
587
|
+
res.writeHead(503, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
588
|
+
return res.end(JSON.stringify({ ok: false, error: DASHBOARD_READ_MESSAGES.scanUnavailable }));
|
|
589
|
+
}
|
|
584
590
|
let repairedCount = 0;
|
|
585
591
|
let failedCount = 0;
|
|
586
592
|
let cleanupMessages = [];
|
|
@@ -782,11 +788,8 @@ return false;}
|
|
|
782
788
|
}
|
|
783
789
|
catch (err) {
|
|
784
790
|
console.error("[Dashboard] Analytics error:", err);
|
|
785
|
-
res.writeHead(
|
|
786
|
-
return res.end(JSON.stringify({
|
|
787
|
-
totalEntries: 0, totalRollups: 0, rollupSavings: 0,
|
|
788
|
-
avgSummaryLength: 0, sessionsByDay: [],
|
|
789
|
-
}));
|
|
791
|
+
res.writeHead(503, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
792
|
+
return res.end(JSON.stringify({ error: DASHBOARD_READ_MESSAGES.analyticsUnavailable }));
|
|
790
793
|
}
|
|
791
794
|
}
|
|
792
795
|
// ─── API: Retention (TTL) Settings (v3.1) ──────────────
|