prism-mcp-server 20.2.1 → 20.2.3
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 +220 -45
- package/dist/browserCli.js +56 -0
- package/dist/cli.js +240 -33
- package/dist/config.js +12 -6
- package/dist/connect.js +848 -15
- package/dist/dashboard/server.js +9 -14
- package/dist/dashboard/settingsPolicy.js +41 -0
- package/dist/localFirstPolicy.js +20 -0
- package/dist/onboarding/wizard.js +3 -6
- package/dist/server.js +77 -65
- package/dist/session/sessionContext.js +5 -3
- package/dist/skillManifestSync.js +943 -0
- package/dist/storage/configStorage.js +110 -1
- package/dist/storage/index.js +4 -3
- package/dist/storage/inferMetricsLedger.js +72 -14
- package/dist/storage/panelMetricsSpool.js +324 -0
- package/dist/storage/synalux.js +18 -1
- package/dist/tools/__tests__/ledgerHandlers.test.js +13 -0
- package/dist/tools/index.js +2 -2
- package/dist/tools/ledgerHandlers.js +468 -53
- package/dist/tools/prismInferHandler.js +171 -12
- package/dist/tools/sessionMemoryDefinitions.js +51 -10
- package/dist/tools/skillRouting.js +39 -7
- package/dist/tools/taskRouterHandler.js +184 -29
- package/dist/utils/inferenceMetrics.js +22 -3
- package/dist/utils/modelPicker.js +3 -3
- package/dist/utils/synaluxJwt.js +2 -1
- package/docs/prism-browser.md +89 -0
- package/package.json +6 -2
- package/scripts/dev/browse.py +1345 -0
package/README.md
CHANGED
|
@@ -18,6 +18,114 @@ A paid subscription adds cloud sync, higher model tiers, and team features throu
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
## What Prism gives you
|
|
22
|
+
|
|
23
|
+
- **Session memory that survives restarts** — resume projects with handoff notes,
|
|
24
|
+
recent work, open TODOs, and configurable quick, standard, or deep context.
|
|
25
|
+
- **Local-first inference** — bounded work is routed through local Ollama models
|
|
26
|
+
first, with automatic 2B/4B/9B/27B selection based on installed models,
|
|
27
|
+
available RAM, context fit, and subscription entitlements.
|
|
28
|
+
- **One setup for every agent** — `prism connect` configures Claude Code,
|
|
29
|
+
Claude Desktop, Cursor, Gemini CLI, and Codex while preserving unrelated
|
|
30
|
+
settings.
|
|
31
|
+
- **Subscription-aware skills** — entitled skills are synchronized before the
|
|
32
|
+
host launches, with safe upgrades, downgrades, conflict preservation, and
|
|
33
|
+
offline last-good recovery.
|
|
34
|
+
- **Hook-free startup** — MCP metadata and native instructions request Prism's
|
|
35
|
+
startup context without requiring lifecycle hooks or a Prism-owned launcher.
|
|
36
|
+
- **Safe escalation and observability** — inference outcomes are explicit,
|
|
37
|
+
reserved content remains fail-closed, and local/cloud usage is recorded for
|
|
38
|
+
review.
|
|
39
|
+
|
|
40
|
+
## Get started
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g prism-mcp-server
|
|
44
|
+
prism connect
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Use `prism connect --dry-run` to preview changes, `prism connect --all` to
|
|
48
|
+
configure every detected host, or `prism connect --refresh` to reconcile
|
|
49
|
+
Prism-managed entries after an upgrade. Restart the host after connecting.
|
|
50
|
+
|
|
51
|
+
Prism works locally without an account, API key, or cloud subscription. Add a
|
|
52
|
+
Synalux subscription when you want cloud memory, paid-tier skills, or team
|
|
53
|
+
features.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
<details>
|
|
58
|
+
<summary>Release history (optional)</summary>
|
|
59
|
+
|
|
60
|
+
## What's New in v20.2.2
|
|
61
|
+
|
|
62
|
+
### One Local-First Workflow Across Every Agent
|
|
63
|
+
`prism connect` now installs one orchestration contract for Claude Code,
|
|
64
|
+
Claude Desktop, Cursor, Gemini CLI, and Codex. Bounded delegated work goes to
|
|
65
|
+
`session_task_route` and the local `prism_infer` worker first; routine work must
|
|
66
|
+
not create background host agents. Local workers can receive the active
|
|
67
|
+
project's dashboard-configured quick, standard, or deep memory and select a
|
|
68
|
+
RAM-safe 2B/4B/9B/27B model at call time. The router forwards complexity but
|
|
69
|
+
does not choose the model; `prism_infer` owns the final decision using memory
|
|
70
|
+
and context fit, installed models, live RAM, entitlements, and explicit caller
|
|
71
|
+
overrides.
|
|
72
|
+
|
|
73
|
+
Codex and Gemini native agent fan-out are disabled during connect. Codex keeps
|
|
74
|
+
a two-thread, one-level Terra/low fallback profile if the developer explicitly
|
|
75
|
+
re-enables native agents later. Claude Code keeps native agents as a last-resort
|
|
76
|
+
path but pins their model to Sonnet. Cursor and Claude Desktop do not expose a
|
|
77
|
+
supported global subagent-policy file, so they receive the identical workflow
|
|
78
|
+
through Prism's MCP server instructions. `prism_infer` safety boundaries and
|
|
79
|
+
the host's final verification responsibility are unchanged.
|
|
80
|
+
|
|
81
|
+
### Subscription-Tier Skills Arrive Before the First Host Launch
|
|
82
|
+
`prism connect` now downloads the authoritative Synalux skill manifest and
|
|
83
|
+
materializes entitled packages in the native `~/.agents/skills` directory
|
|
84
|
+
before the command exits. Codex therefore sees the current skillset on its
|
|
85
|
+
first launch instead of requiring a second restart. Prism rechecks the same
|
|
86
|
+
snapshot at MCP startup, session load, and every five minutes—without host
|
|
87
|
+
lifecycle hooks.
|
|
88
|
+
|
|
89
|
+
On the first user turn, Prism's native skill, MCP metadata, and managed host
|
|
90
|
+
instructions request one `session_bootstrap({})` call. Prism then uses the
|
|
91
|
+
dashboard's developer name, Auto-Load Projects, and quick, standard, or deep
|
|
92
|
+
setting. The response stays focused on greeting and session state because tier
|
|
93
|
+
skills are already present in the host's native skill directory.
|
|
94
|
+
|
|
95
|
+
Hook-free MCP can provide and prioritize that ready-to-display block, but the
|
|
96
|
+
host model still owns the final assistant message and may summarize it. Prism
|
|
97
|
+
does not claim a deterministic verbatim greeting on third-party chat surfaces;
|
|
98
|
+
that would require a host lifecycle hook, launcher, extension, or Prism-owned
|
|
99
|
+
panel. Context loading itself remains complete even when a host shortens the
|
|
100
|
+
visible reply.
|
|
101
|
+
|
|
102
|
+
Free accounts receive the protected 12-skill foundation. Paid accounts receive
|
|
103
|
+
the current subscribed routing set. Upgrades install newly entitled packages;
|
|
104
|
+
downgrades remove only Prism-owned packages while preserving local skills and
|
|
105
|
+
locally modified conflicts.
|
|
106
|
+
|
|
107
|
+
When upgrading an older Claude Code installation, `prism connect` removes only
|
|
108
|
+
the exact Prism-owned startup, skill-sync, handoff, and drift hook actions from
|
|
109
|
+
the legacy bootstrap. It also removes the recognized legacy Prism startup
|
|
110
|
+
sections from `~/CLAUDE.md`, preserves every other instruction, and installs a
|
|
111
|
+
small ownership-marked native block that selects `session_bootstrap({})` on the
|
|
112
|
+
first turn. User hooks, custom instruction sections, and near matches remain
|
|
113
|
+
untouched; native skills and server-side reminders preserve those Prism
|
|
114
|
+
features without host lifecycle hooks. Because hosts expose no native
|
|
115
|
+
session-end callback, handoff at shutdown is instruction-driven rather than a
|
|
116
|
+
guaranteed lifecycle event.
|
|
117
|
+
|
|
118
|
+
After Claude Code's native user registration succeeds, the same default or
|
|
119
|
+
`--refresh` command checks the nearest `.mcp.json` from the current directory
|
|
120
|
+
through the home directory. It removes only the exact legacy
|
|
121
|
+
`prism-mcp` entry `{ "command": "npx", "args": ["-y", "prism-mcp-server"] }`
|
|
122
|
+
that would otherwise shadow the user registration. Custom Prism entries and
|
|
123
|
+
their additional fields, plus unrelated servers, are preserved; malformed
|
|
124
|
+
files fail loud without changes. `--dry-run` reports the recognized migration
|
|
125
|
+
without changing the file.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
21
129
|
## What's New in v20.2.1
|
|
22
130
|
|
|
23
131
|
### Subscription-Aware Memory Storage
|
|
@@ -117,6 +225,8 @@ External contributions now require signing the [Individual CLA](./CLA.md). The C
|
|
|
117
225
|
|
|
118
226
|
---
|
|
119
227
|
|
|
228
|
+
</details>
|
|
229
|
+
|
|
120
230
|
## Quickstart
|
|
121
231
|
|
|
122
232
|
The free tier needs no account, no API key, and no cloud. Install Prism, then
|
|
@@ -133,16 +243,37 @@ Use `prism connect --all` to target all five, `--host <name>` for one host, or
|
|
|
133
243
|
`--dry-run` to preview the files that would change. Existing `prism` and
|
|
134
244
|
`prism-mcp` entries are never overwritten by default. `--refresh` updates only
|
|
135
245
|
an entry previously created by Prism; custom entries remain untouched.
|
|
246
|
+
For Claude Code, both the default command and `--refresh` also remove the exact
|
|
247
|
+
legacy project-scoped `npx -y prism-mcp-server` entry from the effective
|
|
248
|
+
ancestor `.mcp.json` after the native user registration succeeds. No custom or
|
|
249
|
+
near-match project entry is changed.
|
|
136
250
|
Close the target MCP hosts before a non-dry-run registration so they cannot
|
|
137
251
|
edit their configuration at the same time.
|
|
138
252
|
|
|
253
|
+
The same connection installs the local-first orchestration contract:
|
|
254
|
+
|
|
255
|
+
| Host | Managed containment |
|
|
256
|
+
|---|---|
|
|
257
|
+
| Codex | `features.multi_agent=false`; a 2-thread, depth-1 Terra/low fallback profile is retained for explicit re-enable |
|
|
258
|
+
| Gemini CLI | `experimental.enableAgents=false` |
|
|
259
|
+
| Claude Code | `CLAUDE_CODE_SUBAGENT_MODEL=sonnet`; managed instructions reserve it for last-resort fallback |
|
|
260
|
+
| Cursor | Canonical policy delivered through MCP initialize instructions |
|
|
261
|
+
| Claude Desktop | Canonical policy delivered through MCP initialize instructions |
|
|
262
|
+
|
|
263
|
+
All five receive `PRISM_AGENT_POLICY=local-first` in their managed Prism MCP
|
|
264
|
+
entry. Routine tasks use the RAM-aware local worker; native/background fan-out
|
|
265
|
+
is not the default workflow. `session_task_route` supplies a complexity hint;
|
|
266
|
+
`prism_infer` remains the single owner of model and thinking selection and can
|
|
267
|
+
choose 27B when its viability gates support it.
|
|
268
|
+
|
|
139
269
|
Set `PRISM_STORAGE` before running `prism connect` to preserve an explicit
|
|
140
270
|
storage choice in the generated host entries. This does not change local-model
|
|
141
271
|
routing; Synalux cloud storage separately requires an active cloud-memory
|
|
142
272
|
entitlement.
|
|
143
273
|
|
|
144
|
-
Codex registration preserves `~/.codex/config.toml`
|
|
145
|
-
|
|
274
|
+
Codex registration preserves unrelated `~/.codex/config.toml` content, appends
|
|
275
|
+
only the marked Prism MCP block, and updates only the documented local-first
|
|
276
|
+
feature/agent keys. `CODEX_HOME` is respected when set and must already exist,
|
|
146
277
|
matching Codex's own contract. Restart Codex CLI, the
|
|
147
278
|
IDE extension, or the ChatGPT desktop app after connecting.
|
|
148
279
|
|
|
@@ -431,42 +562,44 @@ The quality gate detected repeated sentences (≥3 of the same sentence in ≥6
|
|
|
431
562
|
|
|
432
563
|
### vs AI coding assistants
|
|
433
564
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
|
442
|
-
|
|
443
|
-
|
|
|
444
|
-
|
|
|
445
|
-
|
|
|
446
|
-
|
|
|
447
|
-
|
|
|
448
|
-
|
|
|
565
|
+
Product capabilities and plans change frequently. The comparison below is
|
|
566
|
+
intentionally limited to publicly documented differences; it is not a claim
|
|
567
|
+
that another product lacks an unlisted feature.
|
|
568
|
+
|
|
569
|
+
Legend: ✅ documented, ◐ conditional or plan-dependent, — not compared, ? verify
|
|
570
|
+
with the provider.
|
|
571
|
+
|
|
572
|
+
| Capability | Prism Coder | GitHub Copilot | Cursor | Amazon Q Developer |
|
|
573
|
+
|---|:---:|:---:|:---:|:---:|
|
|
574
|
+
| Local/open-weight inference | ✅ | ◐ | ◐ | ◐ |
|
|
575
|
+
| Offline workflow | ✅ | ◐ | ? | ? |
|
|
576
|
+
| Cross-session memory | ✅ | ◐ ([docs](https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-command-reference)) | ◐ | ◐ |
|
|
577
|
+
| MCP integration | ✅ | ✅ ([docs](https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-command-reference)) | ✅ ([pricing](https://cursor.com/en-US/pricing)) | ◐ |
|
|
578
|
+
| Local-first model routing | ✅ | ◐ | ◐ | ◐ |
|
|
579
|
+
| Session drift and grounding checks | ✅ | — | — | — |
|
|
580
|
+
| Setup surface | ✅ five hosts | ✅ CLI/IDE | ✅ editor/agents | ✅ IDE/CLI ([overview](https://aws.amazon.com/q/developer/build/)) |
|
|
581
|
+
| Pricing model | ✅ Synalux tiers | ◐ | ◐ ([pricing](https://cursor.com/en-US/pricing)) | ✅ free + $19 Pro ([pricing](https://aws.amazon.com/q/developer/pricing/)) |
|
|
582
|
+
|
|
583
|
+
Prism-specific compliance, contractual, and pricing terms are documented in
|
|
584
|
+
the Synalux service agreement. Do not infer a competitor's HIPAA, BAA, or data
|
|
585
|
+
handling status from this table.
|
|
449
586
|
|
|
450
587
|
### vs local AI / memory tools
|
|
451
588
|
|
|
452
589
|
| Feature | Prism Coder | Ollama | LM Studio | Mem0 | Zep |
|
|
453
590
|
|---|:---:|:---:|:---:|:---:|:---:|
|
|
454
|
-
| Local inference cascade | ✅ | ✅ | ✅ |
|
|
455
|
-
| Cloud fallback | ✅ |
|
|
456
|
-
| Persistent
|
|
457
|
-
| Knowledge
|
|
458
|
-
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|---|:---:|:---:|:---:|:---:|
|
|
467
|
-
| **Individual** | **$19/mo** | $10/mo | $20/mo | $19/mo |
|
|
468
|
-
| **Team (5 devs)** | **$49/mo flat** | $95/mo | $200/mo | $95/mo |
|
|
469
|
-
| **Enterprise (25 devs)** | **$99/mo flat** | $195/mo | $1,000/mo | Custom |
|
|
591
|
+
| Local inference cascade | ✅ | ✅ runtime | ✅ app | — | — |
|
|
592
|
+
| Cloud fallback | ✅ optional | — | ◐ provider-dependent | ◐ | ◐ |
|
|
593
|
+
| Persistent memory | ✅ | — | ◐ project context | ✅ | ✅ |
|
|
594
|
+
| Knowledge/tool integration | ✅ MCP + ingestion | ◐ APIs | ◐ integrations | ✅ SDK/API | ✅ SDK/API |
|
|
595
|
+
| MCP server | ✅ native | — | ◐ client integration | ◐ client integration | ◐ client integration |
|
|
596
|
+
|
|
597
|
+
### Pricing
|
|
598
|
+
|
|
599
|
+
Prism's current published tiers are listed below. Competitor pricing is
|
|
600
|
+
usage- and plan-dependent, so consult the provider directly: [GitHub
|
|
601
|
+
Copilot](https://github.com/features/copilot/plans), [Cursor](https://cursor.com/en-US/pricing),
|
|
602
|
+
and [Amazon Q Developer](https://aws.amazon.com/q/developer/pricing/).
|
|
470
603
|
|
|
471
604
|
---
|
|
472
605
|
|
|
@@ -499,7 +632,8 @@ Prism exposes 40+ MCP tools. The core memory loop:
|
|
|
499
632
|
|
|
500
633
|
| Tool | What it does |
|
|
501
634
|
|---|---|
|
|
502
|
-
| `
|
|
635
|
+
| `session_bootstrap` | Hook-free first-turn greeting and dashboard-configured context |
|
|
636
|
+
| `session_load_context` | Explicit project reload or older-server startup fallback |
|
|
503
637
|
| `session_save_ledger` | Append an immutable session log entry |
|
|
504
638
|
| `session_save_handoff` | Save live state for the next session |
|
|
505
639
|
| `knowledge_search` | Semantic + keyword search over all memories |
|
|
@@ -508,7 +642,7 @@ Prism exposes 40+ MCP tools. The core memory loop:
|
|
|
508
642
|
| `verify_behavior` | Pre-edit scenario challenge — catch bad changes before they happen |
|
|
509
643
|
| `knowledge_ingest` | Teach Prism a codebase or document |
|
|
510
644
|
| `prism_infer` | Local-first inference (route/chat/code modes, thinking, cloud escalation) |
|
|
511
|
-
| `inference_metrics` | Session delegation
|
|
645
|
+
| `inference_metrics` | Session delegation or persisted MCP + VS Code panel local/cloud stats |
|
|
512
646
|
|
|
513
647
|
### `prism_infer` — local-first inference with cloud escalation
|
|
514
648
|
|
|
@@ -533,7 +667,7 @@ Full TypeScript signatures live in [`src/tools/`](src/tools/); architecture in [
|
|
|
533
667
|
|
|
534
668
|
### `inference_metrics` — see your local-model usage on demand
|
|
535
669
|
|
|
536
|
-
Call `inference_metrics` anytime mid-session to see how many `prism_infer` calls ran locally vs cloud
|
|
670
|
+
Call `inference_metrics` anytime mid-session to see how many `prism_infer` calls ran locally vs cloud. Use `period: "all"` to atomically import the Synalux VS Code panel spool and include its local-serve rate in the persisted totals:
|
|
537
671
|
|
|
538
672
|
```
|
|
539
673
|
📊 Inference Metrics — local-model delegation (this session):
|
|
@@ -547,28 +681,42 @@ Call `inference_metrics` anytime mid-session to see how many `prism_infer` calls
|
|
|
547
681
|
|
|
548
682
|
The same block also appears automatically in `session_save_ledger` and `session_save_handoff` responses at session end.
|
|
549
683
|
|
|
550
|
-
**Note:**
|
|
684
|
+
**Note:** The default session view tracks this MCP process's `prism_infer` delegation. The all-time view combines persisted MCP calls with Synalux VS Code panel inference. Neither view includes your host model's (Claude's) own token spend; use Claude Code's `/cost` command for that.
|
|
551
685
|
|
|
552
|
-
### Local-model delegation (
|
|
686
|
+
### Local-model delegation (default)
|
|
553
687
|
|
|
554
|
-
|
|
688
|
+
Prism routes qualifying bounded work—bulk classification, field extraction,
|
|
689
|
+
mechanical formatting, test generation, and similar tasks—to local Ollama
|
|
690
|
+
models before any host-native subagent. The agent checks `gate_outcome`,
|
|
691
|
+
verifies the result, and continues in the current host thread when the local
|
|
692
|
+
worker is unavailable, refused, or degraded.
|
|
555
693
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
694
|
+
Pass project memory when the subtask depends on prior work:
|
|
695
|
+
|
|
696
|
+
```json
|
|
697
|
+
{
|
|
698
|
+
"prompt": "Generate the bounded regression-test cases.",
|
|
699
|
+
"project": "prism-mcp",
|
|
700
|
+
"context_depth": "standard",
|
|
701
|
+
"conversation_id": "<from session_bootstrap>",
|
|
702
|
+
"mode": "code",
|
|
703
|
+
"cloud_fallback": false,
|
|
704
|
+
"escalation": "report"
|
|
705
|
+
}
|
|
559
706
|
```
|
|
560
707
|
|
|
561
|
-
|
|
708
|
+
Omit `context_depth` to use the dashboard setting. Turn off the dashboard Task
|
|
709
|
+
Router toggle or set `PRISM_TASK_ROUTER_ENABLED=false` for an explicit opt-out.
|
|
562
710
|
|
|
563
711
|
**Guardrails:**
|
|
564
|
-
- **
|
|
712
|
+
- **Local by default** — an explicit operator opt-out is preserved
|
|
565
713
|
- **Never delegates:** code/text that ships to the user, security/safety logic, planning/reasoning, anything where a silent quality drop isn't obvious
|
|
566
714
|
- **Always verifies:** checks `quality_gate_failed` and `used_cloud` before trusting local output
|
|
567
715
|
|
|
568
716
|
<details>
|
|
569
717
|
<summary>How Prism survives context compaction</summary>
|
|
570
718
|
|
|
571
|
-
The LLM context window is treated as ephemeral scratch space; durable state lives in the persistent store (SQLite locally, the portal in the cloud). Every session begins with a mandatory `
|
|
719
|
+
The LLM context window is treated as ephemeral scratch space; durable state lives in the persistent store (SQLite locally, the portal in the cloud). Every session begins with a mandatory no-argument `session_bootstrap` call, so Prism applies the dashboard's project and quick/standard/deep setting before the agent writes a response. When a project exceeds a threshold (default 50 entries), `session_compact_ledger` summarizes old entries into a rollup, soft-archives the originals, and links them in the graph. See [`docs/COMPACTION.md`](docs/COMPACTION.md)
|
|
572
720
|
</details>
|
|
573
721
|
|
|
574
722
|
---
|
|
@@ -581,10 +729,37 @@ prism save # save ledger + handoff
|
|
|
581
729
|
prism search <query> # search code across repos (exact / regex / symbol / semantic)
|
|
582
730
|
prism review <files...> # AI code review — security, performance, style
|
|
583
731
|
prism scan <files...> # security scan — secrets, licenses, Dockerfile
|
|
732
|
+
prism browser ... # persistent local browser testing and structured automation
|
|
584
733
|
prism push # push local SQLite to the cloud backend
|
|
585
734
|
prism register-models # alias dcostenco/prism-coder:* -> prism-coder:*
|
|
586
735
|
```
|
|
587
736
|
|
|
737
|
+
### `prism browser` — local browser testing
|
|
738
|
+
|
|
739
|
+
The npm package includes Prism's Python/Playwright browser runner; no separate
|
|
740
|
+
Prism Browser app or DMG is required. It adds a stable agent-facing CLI around
|
|
741
|
+
Playwright with reusable named profiles, multi-action pipe/REPL sessions,
|
|
742
|
+
redacted local audit logs, and guarded preload scripts for local apps. Use pipe
|
|
743
|
+
or REPL mode when several actions must share one page session:
|
|
744
|
+
|
|
745
|
+
```bash
|
|
746
|
+
printf 'open http://127.0.0.1:3000\nwait-for #app\nread-dom #app\n' | \
|
|
747
|
+
prism browser --headless --local-only pipe
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
Local apps can load repeatable pre-navigation test helpers with
|
|
751
|
+
`--inject ./tests/browser-init.js`. Custom injection requires `--local-only`;
|
|
752
|
+
public navigation and non-loopback requests are rejected in that mode. Install
|
|
753
|
+
the local runtime once with `pip3 install playwright playwright-stealth` and
|
|
754
|
+
`python3 -m playwright install chromium`.
|
|
755
|
+
|
|
756
|
+
Use raw Playwright for authored suites that need its full assertion, tracing,
|
|
757
|
+
fixture, and parallel-worker APIs. Use `prism browser` when an AI agent needs a
|
|
758
|
+
small, persistent, auditable local browser session through one consistent CLI.
|
|
759
|
+
The compatibility patches are best effort; they are not a CAPTCHA-bypass
|
|
760
|
+
guarantee. See [Prism Browser local testing](docs/prism-browser.md) for the
|
|
761
|
+
command surface, safety model, and verified acceptance cases.
|
|
762
|
+
|
|
588
763
|
### `prism search` — semantic code search
|
|
589
764
|
|
|
590
765
|
<p align="center">
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
export function resolveBundledBrowserScript() {
|
|
5
|
+
return fileURLToPath(new URL('../scripts/dev/browse.py', import.meta.url));
|
|
6
|
+
}
|
|
7
|
+
export function pythonCandidates(env = process.env, platform = process.platform) {
|
|
8
|
+
if (env.PRISM_PYTHON) {
|
|
9
|
+
return [{ executable: env.PRISM_PYTHON, prefixArgs: [] }];
|
|
10
|
+
}
|
|
11
|
+
return platform === 'win32'
|
|
12
|
+
? [
|
|
13
|
+
{ executable: 'py', prefixArgs: ['-3'] },
|
|
14
|
+
{ executable: 'python', prefixArgs: [] },
|
|
15
|
+
]
|
|
16
|
+
: [
|
|
17
|
+
{ executable: 'python3', prefixArgs: [] },
|
|
18
|
+
{ executable: 'python', prefixArgs: [] },
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
export function resolvePythonCommand(env = process.env, platform = process.platform) {
|
|
22
|
+
for (const candidate of pythonCandidates(env, platform)) {
|
|
23
|
+
const result = spawnSync(candidate.executable, [...candidate.prefixArgs, '--version'], { env, encoding: 'utf8', shell: false });
|
|
24
|
+
if (!result.error && result.status === 0)
|
|
25
|
+
return candidate;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
export function hasPlaywrightRuntime(python, env = process.env) {
|
|
30
|
+
const result = spawnSync(python.executable, [...python.prefixArgs, '-c', 'import playwright.sync_api'], { env, encoding: 'utf8', shell: false });
|
|
31
|
+
return !result.error && result.status === 0;
|
|
32
|
+
}
|
|
33
|
+
export async function runBrowserCli(args, env = process.env) {
|
|
34
|
+
const scriptPath = resolveBundledBrowserScript();
|
|
35
|
+
if (!existsSync(scriptPath)) {
|
|
36
|
+
throw new Error(`Bundled Prism Browser script is missing: ${scriptPath}`);
|
|
37
|
+
}
|
|
38
|
+
const python = resolvePythonCommand(env);
|
|
39
|
+
if (!python) {
|
|
40
|
+
throw new Error('Python 3 is required for Prism Browser. Set PRISM_PYTHON to a Python 3 executable.');
|
|
41
|
+
}
|
|
42
|
+
if (!args.includes('--help') && !args.includes('-h') && !hasPlaywrightRuntime(python, env)) {
|
|
43
|
+
throw new Error('Python Playwright is required. Run: pip3 install playwright playwright-stealth && python3 -m playwright install chromium');
|
|
44
|
+
}
|
|
45
|
+
return await new Promise((resolve, reject) => {
|
|
46
|
+
const child = spawn(python.executable, [...python.prefixArgs, scriptPath, ...args], { env, shell: false, stdio: 'inherit' });
|
|
47
|
+
child.once('error', reject);
|
|
48
|
+
child.once('exit', (code, signal) => {
|
|
49
|
+
if (signal) {
|
|
50
|
+
reject(new Error(`Prism Browser terminated by signal ${signal}`));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
resolve(code ?? 1);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|