prism-mcp-server 20.2.2 → 20.2.4
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 +114 -31
- package/dist/browserCli.js +56 -0
- package/dist/cli.js +69 -22
- package/dist/storage/synalux.js +42 -23
- package/dist/tools/ledgerHandlers.js +78 -26
- package/dist/utils/memoryQuality.js +51 -0
- package/dist/utils/startupRecovery.js +13 -0
- package/docs/prism-browser.md +89 -0
- package/package.json +4 -2
- package/scripts/dev/browse.py +1345 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const SOURCE_LABEL_PATTERN = /^\s*\[[^\]]+\]\s*/u;
|
|
2
|
+
const GREETING_ONLY_PATTERN = /^(?:hi|hello|hey|ready)(?:[\s.!?,…—-]|[\u{1F300}-\u{1FAFF}]|\uFE0F)*$/iu;
|
|
3
|
+
const GREETING_OPENING_PATTERN = /^(?:hi(?:\s+there)?|hello|hey)\b/iu;
|
|
4
|
+
const ASSISTANCE_INVITATION_PATTERN = /\b(?:(?:how|what)\s+(?:can|may)\s+i\s+(?:help|assist)|let\s+me\s+know\s+what\s+you\s+need)\b/iu;
|
|
5
|
+
const SUBSTANTIVE_OUTCOME_PATTERN = /\b(?:added|built|changed|completed|configured|created|debugged|deployed|fixed|implemented|investigated|removed|repaired|resolved|tested|updated|verified|wrote)\b/iu;
|
|
6
|
+
const STRUCTURED_WORK_FIELDS = ["decisions", "todos", "files_changed"];
|
|
7
|
+
function hasStructuredWork(entry) {
|
|
8
|
+
return STRUCTURED_WORK_FIELDS.some((field) => {
|
|
9
|
+
const value = entry[field];
|
|
10
|
+
if (value === undefined || value === null)
|
|
11
|
+
return false;
|
|
12
|
+
return !Array.isArray(value) || value.length > 0;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
/** Greeting-only assistant replies are presentation, not durable work. */
|
|
16
|
+
export function isGreetingOnlyMemoryEntry(entry) {
|
|
17
|
+
if (hasStructuredWork(entry))
|
|
18
|
+
return false;
|
|
19
|
+
if (typeof entry.event_type === "string" && entry.event_type !== "session")
|
|
20
|
+
return false;
|
|
21
|
+
if (typeof entry.summary !== "string")
|
|
22
|
+
return false;
|
|
23
|
+
const summary = entry.summary.replace(SOURCE_LABEL_PATTERN, "").trim();
|
|
24
|
+
if (!summary)
|
|
25
|
+
return false;
|
|
26
|
+
if (GREETING_ONLY_PATTERN.test(summary))
|
|
27
|
+
return true;
|
|
28
|
+
return GREETING_OPENING_PATTERN.test(summary)
|
|
29
|
+
&& ASSISTANCE_INVITATION_PATTERN.test(summary)
|
|
30
|
+
&& !SUBSTANTIVE_OUTCOME_PATTERN.test(summary);
|
|
31
|
+
}
|
|
32
|
+
export function filterGreetingOnlyMemoryEntries(entries) {
|
|
33
|
+
return entries.filter((entry) => !isGreetingOnlyMemoryEntry(entry));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Defensive local-storage fallback for the portal-owned memory policy.
|
|
37
|
+
* Returns a copy so storage responses remain immutable for other consumers.
|
|
38
|
+
*/
|
|
39
|
+
export function filterPrismMemoryContext(data) {
|
|
40
|
+
const filtered = { ...data };
|
|
41
|
+
if (isGreetingOnlyMemoryEntry({ summary: data.last_summary })) {
|
|
42
|
+
filtered.last_summary = null;
|
|
43
|
+
}
|
|
44
|
+
if (Array.isArray(data.recent_sessions)) {
|
|
45
|
+
filtered.recent_sessions = filterGreetingOnlyMemoryEntries(data.recent_sessions);
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(data.session_history)) {
|
|
48
|
+
filtered.session_history = filterGreetingOnlyMemoryEntries(data.session_history);
|
|
49
|
+
}
|
|
50
|
+
return filtered;
|
|
51
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const RECOVERABLE_STARTUP_STORAGE_ERROR = /(?:rate limit|(?:HTTP|status)\s*(?:408|425|429|5\d{2})\b|network error|fetch failed|timed?\s*out|timeout|ECONN(?:RESET|REFUSED)|ENOTFOUND|EAI_AGAIN|socket hang up)/i;
|
|
2
|
+
const RECOVERABLE_ENTITLEMENT_PROBE_ERROR = /\[Prism Storage\]\s+Could not verify the Synalux cloud-memory entitlement\b/i;
|
|
3
|
+
export const LOCAL_STARTUP_FALLBACK_NOTICE = "⚠️ Synalux cloud context is temporarily unavailable; showing local last-good context for this startup only.";
|
|
4
|
+
/**
|
|
5
|
+
* Startup may degrade to the local last-good snapshot only for transient
|
|
6
|
+
* storage failures. Validation, formatting, and programmer errors must still
|
|
7
|
+
* fail loud instead of being hidden by an unrelated fallback.
|
|
8
|
+
*/
|
|
9
|
+
export function isRecoverableStartupStorageError(error) {
|
|
10
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
11
|
+
return RECOVERABLE_STARTUP_STORAGE_ERROR.test(message)
|
|
12
|
+
|| RECOVERABLE_ENTITLEMENT_PROBE_ERROR.test(message);
|
|
13
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Prism Browser local testing
|
|
2
|
+
|
|
3
|
+
`prism browser` is a packaged, agent-facing local browser runner powered by
|
|
4
|
+
Python Playwright. It is intended for repeatable development and acceptance
|
|
5
|
+
checks against applications you control. The npm package contains the runner,
|
|
6
|
+
so a separate app or DMG is not required.
|
|
7
|
+
|
|
8
|
+
## What it adds to Playwright
|
|
9
|
+
|
|
10
|
+
- **One CLI across agents.** Codex, Claude, Gemini, Cursor, and shell workflows
|
|
11
|
+
can invoke the same structured commands when Prism is connected.
|
|
12
|
+
- **Persistent named profiles.** `--profile NAME` reuses Chromium state across
|
|
13
|
+
launches instead of requiring every agent to build profile management.
|
|
14
|
+
- **Low-overhead multi-step sessions.** Pipe and REPL modes keep one browser
|
|
15
|
+
session alive while several navigation, DOM, input, wait, and evaluation
|
|
16
|
+
commands run.
|
|
17
|
+
- **Local preload helpers.** Repeatable `--inject` scripts run before page
|
|
18
|
+
scripts, allowing deterministic feature flags, fixtures, capability shims,
|
|
19
|
+
or instrumentation for localhost tests.
|
|
20
|
+
- **A constrained injection boundary.** Injection requires `--local-only`,
|
|
21
|
+
which rejects public navigation and non-loopback subrequests.
|
|
22
|
+
- **Private audit records.** The runner stores a local audit trail with private
|
|
23
|
+
filesystem permissions and removes URL credentials, query strings,
|
|
24
|
+
fragments, common email/phone patterns, and injected source text.
|
|
25
|
+
|
|
26
|
+
These are orchestration and safety benefits. Prism Browser does not replace
|
|
27
|
+
Playwright Test: use raw Playwright when you need its complete fixture,
|
|
28
|
+
assertion, trace, project, or parallel-worker APIs. Compatibility patches are
|
|
29
|
+
best effort and are not a CAPTCHA-bypass guarantee.
|
|
30
|
+
|
|
31
|
+
## Install the local runtime
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip3 install playwright playwright-stealth
|
|
35
|
+
python3 -m playwright install chromium
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The npm package supplies `scripts/dev/browse.py`; the Python runtime supplies
|
|
39
|
+
the browser engine. To use a specific Python installation, set
|
|
40
|
+
`PRISM_PYTHON=/absolute/path/to/python3`.
|
|
41
|
+
|
|
42
|
+
## Local acceptance flow
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
printf 'open http://127.0.0.1:3000\nwait-for #app\nread-dom #app\n' | \
|
|
46
|
+
prism browser --headless --local-only --profile acceptance pipe
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
To install a helper before the application's own scripts:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
prism browser \
|
|
53
|
+
--headless \
|
|
54
|
+
--local-only \
|
|
55
|
+
--profile acceptance \
|
|
56
|
+
--inject ./tests/browser-init.js \
|
|
57
|
+
open http://127.0.0.1:3000
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
An injected file must be a regular, non-symlinked UTF-8 `.js` or `.mjs` file
|
|
61
|
+
no larger than 256 KiB. The audit log records its SHA-256 digest, not its path
|
|
62
|
+
or contents.
|
|
63
|
+
|
|
64
|
+
## Verified acceptance cases
|
|
65
|
+
|
|
66
|
+
The public test suite verifies that:
|
|
67
|
+
|
|
68
|
+
1. The npm allowlist contains the runner and the compiled CLI resolves it.
|
|
69
|
+
2. A named profile retains state across two separate Chromium launches.
|
|
70
|
+
3. Pipe commands share one live page session.
|
|
71
|
+
4. A preload helper is visible to the application's first page script.
|
|
72
|
+
5. A public subrequest and direct public navigation are blocked in
|
|
73
|
+
`--local-only` mode.
|
|
74
|
+
6. Audit files use private permissions and omit tested URL secrets, PHI-like
|
|
75
|
+
values, and injected source.
|
|
76
|
+
7. Missing Python/Playwright dependencies fail with an actionable error.
|
|
77
|
+
|
|
78
|
+
Run the focused contract with the repository watchdog:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
MIN_FREE_GB=2 \
|
|
82
|
+
/path/to/playwright-watchdog.sh \
|
|
83
|
+
--exec npx vitest run tests/browser-cli.test.ts
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The Synalux skill-routing tests separately verify that an authenticated paid
|
|
87
|
+
skill request can receive `local-browser`, while a free request does not. The
|
|
88
|
+
subscription controls skill delivery; the browser runtime still executes on
|
|
89
|
+
the user's machine.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prism-mcp-server",
|
|
3
|
-
"version": "20.2.
|
|
3
|
+
"version": "20.2.4",
|
|
4
4
|
"mcpName": "io.github.dcostenco/prism-coder",
|
|
5
5
|
"description": "Prism Coder — Cognitive memory + tool-calling intelligence for AI agents. Mind Palace persistent memory (BFCL Gold Certified, 100% Tool-Call Accuracy, 114 Agent Skills, PHI Guard, Tier Enforcement, Prompt-Based Skill Routing, Zero-Search HDC/HRR retrieval, HRR Semantic Drift Detection across BCBA/Coding/AAC domains, HIPAA-hardened local or subscription-gated Synalux storage, SLERP-optimized GRPO alignment) plus the prism-coder 1.7B–32B open-weights LLM fleet.",
|
|
6
6
|
"module": "index.ts",
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
"prism-import": "dist/utils/universalImporter.js"
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
|
-
"dist"
|
|
16
|
+
"dist",
|
|
17
|
+
"scripts/dev/browse.py",
|
|
18
|
+
"docs/prism-browser.md"
|
|
17
19
|
],
|
|
18
20
|
"scripts": {
|
|
19
21
|
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|