@arnilo/prism 0.3.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -1
- package/README.md +42 -62
- package/dist/agent-run-lifecycle.js +4 -0
- package/dist/agent-run-state.d.ts +5 -2
- package/dist/agent-run-state.js +18 -8
- package/dist/agent-session/session/assemble.d.ts +6 -0
- package/dist/agent-session/session/assemble.js +391 -0
- package/dist/agent-session/session/persist.d.ts +28 -0
- package/dist/agent-session/session/persist.js +166 -0
- package/dist/agent-session/session/provider-round.d.ts +6 -0
- package/dist/agent-session/session/provider-round.js +231 -0
- package/dist/agent-session/session/tool-round.d.ts +31 -0
- package/dist/agent-session/session/tool-round.js +473 -0
- package/dist/agent-session/session/types.d.ts +115 -0
- package/dist/agent-session/session/types.js +5 -0
- package/dist/agent-session/session.d.ts +54 -41
- package/dist/agent-session/session.js +23 -1132
- package/dist/capture.d.ts +63 -0
- package/dist/capture.js +67 -0
- package/dist/cli-dev.d.ts +29 -0
- package/dist/cli-dev.js +52 -0
- package/dist/cli-init.d.ts +34 -3
- package/dist/cli-init.js +192 -24
- package/dist/cli-runner.d.ts +6 -2
- package/dist/cli-runner.js +57 -10
- package/dist/content.d.ts +3 -3
- package/dist/content.js +3 -1
- package/dist/contracts-core/agent.d.ts +8 -0
- package/dist/contracts-core/batch.d.ts +97 -0
- package/dist/contracts-core/batch.js +65 -0
- package/dist/contracts-core/content.d.ts +72 -1
- package/dist/contracts-core/embeddings.d.ts +30 -0
- package/dist/contracts-core/embeddings.js +17 -0
- package/dist/contracts-core/images.d.ts +60 -0
- package/dist/contracts-core/images.js +17 -0
- package/dist/contracts-core/moderation.d.ts +46 -0
- package/dist/contracts-core/moderation.js +34 -0
- package/dist/contracts-core/speech.d.ts +39 -0
- package/dist/contracts-core/speech.js +17 -0
- package/dist/contracts-core/transcription.d.ts +48 -0
- package/dist/contracts-core/transcription.js +17 -0
- package/dist/contracts-core/video.d.ts +61 -0
- package/dist/contracts-core/video.js +17 -0
- package/dist/contracts-core.d.ts +7 -0
- package/dist/contracts-core.js +7 -0
- package/dist/contracts-protocol.d.ts +18 -0
- package/dist/contracts-run-state.d.ts +1 -2
- package/dist/index.d.ts +7 -3
- package/dist/index.js +5 -3
- package/dist/input.d.ts +8 -0
- package/dist/input.js +4 -0
- package/dist/node/agent-definitions.d.ts +1 -8
- package/dist/node/agent-definitions.js +0 -34
- package/dist/node/settings.d.ts +0 -1
- package/dist/node/settings.js +0 -5
- package/dist/pinned-fetch.js +29 -3
- package/dist/provider-events.js +3 -4
- package/dist/providers/media.d.ts +1 -2
- package/dist/providers/media.js +1 -4
- package/dist/rpc.d.ts +1 -1
- package/dist/rpc.js +4 -4
- package/dist/testing/persistence-schema.d.ts +1 -1
- package/dist/testing/persistence-schema.js +32 -28
- package/dist/testing/provider-conformance.d.ts +114 -5
- package/dist/testing/provider-conformance.js +342 -0
- package/dist/testing/tool-conformance.d.ts +25 -0
- package/dist/testing/tool-conformance.js +128 -1
- package/dist/testing/tool-effect-store-conformance.d.ts +0 -1
- package/dist/testing/tool-effect-store-conformance.js +0 -3
- package/dist/thinking.d.ts +48 -9
- package/dist/thinking.js +134 -8
- package/dist/tool-search.d.ts +76 -0
- package/dist/tool-search.js +199 -0
- package/docs/0.1.0-readiness.md +3 -3
- package/docs/a2a.md +2 -2
- package/docs/acp-agent.md +1 -1
- package/docs/acp.md +3 -3
- package/docs/ag-ui-adoption.md +1 -1
- package/docs/ag-ui.md +1 -2
- package/docs/agent-definitions.md +1 -1
- package/docs/agent-events.md +5 -5
- package/docs/agent-identity.md +13 -2
- package/docs/audit-export.md +3 -3
- package/docs/batch-jobs.md +120 -0
- package/docs/browser-automation.md +5 -5
- package/docs/caveman.md +2 -2
- package/docs/cli-rpc.md +43 -9
- package/docs/coding-agent-tools.md +19 -19
- package/docs/coding-review-and-diagnostics.md +2 -2
- package/docs/coding-security.md +5 -5
- package/docs/coding-tools.md +82 -0
- package/docs/coding-workspaces.md +2 -2
- package/docs/compaction-and-retry.md +2 -2
- package/docs/compaction-llm.md +4 -4
- package/docs/compaction-observational-memory.md +3 -3
- package/docs/computer-use-linux.md +13 -2
- package/docs/context-and-skills.md +3 -1
- package/docs/conversations.md +4 -4
- package/docs/core.md +85 -0
- package/docs/credential-storage.md +12 -8
- package/docs/credentials-and-redaction.md +1 -1
- package/docs/data-classification.md +1 -1
- package/docs/database-persistence.md +7 -3
- package/docs/dev-inspector.md +103 -0
- package/docs/device-adapters.md +2 -2
- package/docs/diagrams.md +247 -0
- package/docs/document-reader.md +6 -6
- package/docs/documents.md +214 -0
- package/docs/embeddings.md +112 -0
- package/docs/enterprise-postgres-state.md +7 -7
- package/docs/evaluations.md +41 -7
- package/docs/extensions.md +3 -3
- package/docs/forge-integration.md +3 -3
- package/docs/graft.md +5 -5
- package/docs/guardrails.md +2 -2
- package/docs/host-security.md +16 -15
- package/docs/image-generation.md +129 -0
- package/docs/impeccable.md +7 -5
- package/docs/index.md +84 -46
- package/docs/indexed-code-search.md +2 -2
- package/docs/language-intelligence.md +4 -4
- package/docs/live-testing.md +126 -0
- package/docs/mcp-tools.md +44 -13
- package/docs/middleware-hooks.md +1 -1
- package/docs/migrate-to-0.4.md +312 -0
- package/docs/migrate-to-0.5.md +122 -0
- package/docs/migration.md +51 -1
- package/docs/model-registry.md +38 -0
- package/docs/model-routing.md +6 -6
- package/docs/moderation.md +117 -0
- package/docs/multi-agent-patterns.md +177 -0
- package/docs/multimodal-content.md +27 -3
- package/docs/obscura.md +12 -12
- package/docs/observability.md +32 -7
- package/docs/openapi-tools.md +14 -4
- package/docs/operations.md +11 -0
- package/docs/performance.md +30 -10
- package/docs/persistence-credentials-multimodality-primitives.md +7 -7
- package/docs/policy-and-audit.md +18 -8
- package/docs/ponytail.md +3 -3
- package/docs/postgres-persistence.md +5 -5
- package/docs/process-sessions.md +2 -2
- package/docs/prompt-registry.md +106 -0
- package/docs/provider-caching.md +36 -32
- package/docs/provider-conformance.md +24 -2
- package/docs/provider-packages.md +58 -22
- package/docs/provider-primitives.md +5 -5
- package/docs/provider-request-policies.md +1 -1
- package/docs/providers/ai-sdk.md +18 -6
- package/docs/providers/alibaba.md +10 -6
- package/docs/providers/anthropic.md +10 -6
- package/docs/providers/azure.md +20 -4
- package/docs/providers/bedrock.md +18 -3
- package/docs/providers/clinepass.md +7 -3
- package/docs/providers/commandcode.md +253 -0
- package/docs/providers/deepseek.md +7 -3
- package/docs/providers/google.md +8 -4
- package/docs/providers/hyper.md +284 -0
- package/docs/providers/kimi.md +7 -3
- package/docs/providers/neuralwatt.md +12 -8
- package/docs/providers/ollama.md +18 -3
- package/docs/providers/openai-compatible.md +5 -1
- package/docs/providers/openai.md +9 -5
- package/docs/providers/opencode-go.md +8 -4
- package/docs/providers/openrouter.md +8 -4
- package/docs/providers/vertex.md +21 -5
- package/docs/providers/xai.md +7 -3
- package/docs/providers/zai.md +7 -3
- package/docs/rag.md +31 -9
- package/docs/release-and-install.md +181 -76
- package/docs/resource-loading.md +1 -1
- package/docs/runs-and-usage.md +28 -3
- package/docs/server.md +94 -5
- package/docs/settings-auth-trust-security.md +7 -5
- package/docs/sheets.md +229 -0
- package/docs/speech.md +126 -0
- package/docs/sqlite-persistence.md +4 -4
- package/docs/supervisors.md +4 -3
- package/docs/thinking-and-reasoning.md +93 -60
- package/docs/tool-conformance.md +28 -3
- package/docs/tool-execution-primitives.md +8 -8
- package/docs/tools.md +32 -5
- package/docs/web-tools.md +3 -3
- package/docs/wiki.md +7 -7
- package/docs/work-artifacts-and-review.md +17 -6
- package/docs/work-connectors.md +4 -4
- package/docs/work-tools.md +5 -5
- package/docs/workflow-orchestration-primitives.md +35 -11
- package/docs/workflows.md +74 -13
- package/docs/working-and-semantic-memory.md +53 -5
- package/package.json +14 -31
- package/templates/README.md +23 -0
- package/templates/deep-research/README.md.tmpl +47 -0
- package/templates/deep-research/env.example.tmpl +12 -0
- package/templates/deep-research/gitignore.tmpl +7 -0
- package/templates/deep-research/manifest.json +12 -0
- package/templates/deep-research/package.json.tmpl +23 -0
- package/templates/deep-research/src/agent.ts.tmpl +81 -0
- package/templates/deep-research/src/index.ts.tmpl +53 -0
- package/templates/deep-research/src/tests/research.test.ts.tmpl +114 -0
- package/templates/deep-research/src/tools.ts.tmpl +86 -0
- package/templates/deep-research/src/types.ts.tmpl +45 -0
- package/templates/deep-research/src/workflow.ts.tmpl +156 -0
- package/templates/deep-research/tsconfig.json.tmpl +15 -0
- package/templates/init/manifest.json +5 -0
- package/templates/init/package.json.tmpl +2 -1
- package/templates/init/providers.json +40 -24
- package/docs/antigravity-agent.md +0 -207
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Live and end-to-end testing
|
|
2
|
+
|
|
3
|
+
## What it does
|
|
4
|
+
|
|
5
|
+
Prism ships three network-free test tiers by default (`npm test`, per-package `node --test` suites, and packed-consumer journeys) plus an opt-in **live matrix** that runs the same public surface against real credentials. This page documents how to run the live matrix, which credentials each suite needs, and the guarantees the harness gives you: a missing credential skips its suite (never fails), and secrets never enter the repo, logs, or reports.
|
|
6
|
+
|
|
7
|
+
## When to use it
|
|
8
|
+
|
|
9
|
+
- Before a release: prove every public export subpath still works over a real wire or real process, not just against fakes.
|
|
10
|
+
- After adding a provider or protocol adapter: add a live suite, register it in `scripts/live-matrix.json`, and the coverage gate + doc-check keep the docs honest.
|
|
11
|
+
- In CI: scheduled canaries probe deployed endpoints; strict mode is available for release gates.
|
|
12
|
+
|
|
13
|
+
## Coverage definition (what "100%" means)
|
|
14
|
+
|
|
15
|
+
- **Functional-surface 100%:** every public export subpath across the ten first-party packages (98 subpaths, tracked in `scripts/e2e-coverage.json`) is exercised by at least one suite — a hermetic unit test, a real-wire live test, a real-binary leg, or the full-surface packed journey (`scripts/e2e-full-surface.test.mjs`). The gate is `node scripts/e2e-coverage-gate.mjs` (baseline mode fails only on regressions).
|
|
16
|
+
- **Line-ratchet caveat:** the per-package line-coverage thresholds in `scripts/coverage-thresholds.json` are measured by the network-free `npm test` run only. Live suites intentionally do not contribute to line coverage; 100% functional-surface coverage does not mean 100% line coverage of every branch under live conditions.
|
|
17
|
+
|
|
18
|
+
## Running the matrix
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
npm run test:live # run active suites whose credentials are present
|
|
22
|
+
node scripts/live-matrix.mjs --check # validate manifest + per-suite skip/run table (no spawns)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| knob | effect |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `PRISM_LIVE_ENV_FILE` | credential file, loaded with Node `--env-file` semantics. Default: `scripts/live.env` when present. Copy `scripts/live.env.example` to start. |
|
|
28
|
+
| `PRISM_LIVE_FILTER=<sub>` | only suites whose id contains `<sub>` |
|
|
29
|
+
| `PRISM_LIVE_STRICT=1` | any skip fails the **run** (exit 1), not the suite — for release gates |
|
|
30
|
+
| `PRISM_LIVE_DRY_RUN=1` | accounting only, no spawns |
|
|
31
|
+
| `PRISM_LIVE_CONCURRENCY=n` | parallel suites (default 1, sequential) |
|
|
32
|
+
| `PRISM_LIVE_SUITE_TIMEOUT_MS` | per-suite kill timer (default 600000) |
|
|
33
|
+
|
|
34
|
+
### Skip-not-fail contract
|
|
35
|
+
|
|
36
|
+
A suite whose required credentials are absent is **skipped with a reason**, never failed. `scripts/live-matrix.json` encodes the contract per suite (`requires` all-of, `requiresAny` any-of, `optional` extras); `resolveSuiteState()` is the pure implementation the runner and the `--check` table share. Strict mode inverts the semantics deliberately: with `PRISM_LIVE_STRICT=1` a skip fails the run, because a release gate wants proof the credentials were present and the wires were exercised.
|
|
37
|
+
|
|
38
|
+
### Model selection
|
|
39
|
+
|
|
40
|
+
Every provider suite reads `PRISM_LIVE_<PROVIDER>_MODEL` to pin the model under test (multi-probe suites suffix `_CHAT_MODEL` / `_MESSAGES_MODEL` / `_GPT_MODEL`). Each manifest row records the wired env var and its cost-bounded default, so cost stays predictable. `wired: false` means the suite does not read that env var yet.
|
|
41
|
+
|
|
42
|
+
### Report
|
|
43
|
+
|
|
44
|
+
Each run writes `docs/_evidence/live-matrix-report.{json,md}`: per-suite status/duration/detail, totals, a filter/strict/dry-run annotation, and an e2e surface-coverage summary. The report contains env var **names** and model ids — never secret values.
|
|
45
|
+
|
|
46
|
+
## Credential matrix
|
|
47
|
+
|
|
48
|
+
Set only the rows you want to run; everything else skips. Least-privilege scope is mandatory per row: issue the narrowest credential that satisfies the named probe. Credentials live in `scripts/live.env` (gitignored) or `~/.config/prism/live.env` (out-of-repo), never in the repository, test fixtures, or CI logs; the journey suites assert the `assertNoSecretLeak` convention (from `@arnilo/prism/testing/*`) over every transcript they produce, and the manifest validator rejects secret-shaped values.
|
|
49
|
+
|
|
50
|
+
<!-- generated:live-matrix:start -->
|
|
51
|
+
| suite | status | required credentials | model override | least-privilege scope | cost |
|
|
52
|
+
|---|---|---|---|---|---|
|
|
53
|
+
| `providers/openai` | active | `PRISM_LIVE_PROVIDER_TESTS` + `OPENAI_API_KEY` | `PRISM_LIVE_OPENAI_MODEL` (default `gpt-5.1`) | Project-scoped chat-completion key; least privilege: restrict to chat models. | 2 requests (1 text, 1 tool-call) on the configured model. |
|
|
54
|
+
| `providers/anthropic` | active | `PRISM_LIVE_PROVIDER_TESTS` + `ANTHROPIC_API_KEY` | `PRISM_LIVE_ANTHROPIC_MODEL` (default `claude-haiku-4-5`) | Chat-completion key. | 2 requests. |
|
|
55
|
+
| `providers/google` | active | `PRISM_LIVE_PROVIDER_TESTS`; any of: `GEMINI_API_KEY` / `GOOGLE_API_KEY` | `PRISM_LIVE_GOOGLE_MODEL` (default `gemini-2.5-flash-lite`) | Gemini API key (either var). | 2 requests. |
|
|
56
|
+
| `providers/alibaba` | active | `PRISM_LIVE_PROVIDER_TESTS` + `PRISM_LIVE_DASHSCOPE_KEY` | `PRISM_LIVE_DASHSCOPE_MODEL` (default `text-embedding-v4`) | DashScope key. | 2 requests (embedding/roundtrip class). |
|
|
57
|
+
| `providers/clinepass` | active | `PRISM_LIVE_PROVIDER_TESTS` + `CLINE_API_KEY` | `PRISM_LIVE_CLINEPASS_MODEL` (default `cline-pass/deepseek-v4-flash`) | Cline provider key. | 2 requests. |
|
|
58
|
+
| `providers/commandcode` | active | `PRISM_LIVE_PROVIDER_TESTS` + `COMMAND_CODE_API_KEY` | `PRISM_LIVE_COMMANDCODE_CHAT_MODEL` (default `Qwen/Qwen3.8-Flash`), `PRISM_LIVE_COMMANDCODE_MESSAGES_MODEL` (default `claude-haiku-4-5-20251001`), `PRISM_LIVE_COMMANDCODE_GPT_MODEL` (default `gpt-5.6-luna`) | Command Code key; probes three cheap routed models. | 3-4 requests on cheap models. |
|
|
59
|
+
| `providers/deepseek` | active | `PRISM_LIVE_PROVIDER_TESTS` + `DEEPSEEK_API_KEY` | `PRISM_LIVE_DEEPSEEK_MODEL` (default `deepseek-v4-flash`) | DeepSeek key. | 2 requests on flash-class model. |
|
|
60
|
+
| `providers/hyper` | active | `PRISM_LIVE_PROVIDER_TESTS` + `HYPER_API_KEY` | `PRISM_LIVE_HYPER_CHAT_MODEL` (default `deepseek-v4-pro`), `PRISM_LIVE_HYPER_MESSAGES_MODEL` (default `qwen3.6-plus`) | Hyper key; second model probes the exact-prefix cache. | ~4 requests incl. ~1 KiB prefix cache write; sub-cent. |
|
|
61
|
+
| `providers/kimi` | active | `PRISM_LIVE_PROVIDER_TESTS` + `KIMI_API_KEY` | `PRISM_LIVE_KIMI_MODEL` (default `kimi-for-coding`) | Kimi coding-plan credential. | 2 requests. |
|
|
62
|
+
| `providers/neuralwatt` | active | `PRISM_LIVE_PROVIDER_TESTS` + `NEURALWATT_API_KEY` | `PRISM_LIVE_NEURALWATT_MODEL` (default `glm-5.2`) | NeuralWatt key. | 2 requests. |
|
|
63
|
+
| `providers/opencode-go` | active | `PRISM_LIVE_PROVIDER_TESTS` + `OPENCODE_API_KEY` | `PRISM_LIVE_OPENCODE_MODEL` (default `mimo-v2.5`) | OpenCode Go key. | 2 requests. |
|
|
64
|
+
| `providers/openrouter` | active | `PRISM_LIVE_PROVIDER_TESTS` + `OPENROUTER_API_KEY` | `PRISM_LIVE_OPENROUTER_MODEL` (default `anthropic/claude-sonnet-4`) | OpenRouter key (any routed model id). | 2 requests. |
|
|
65
|
+
| `providers/xai` | active | `PRISM_LIVE_PROVIDER_TESTS` + `XAI_API_KEY`; optional: `PRISM_LIVE_XAI_OAUTH` | `PRISM_LIVE_XAI_MODEL` (default `grok-4.6`) | xAI key; OAuth leg additionally needs PRISM_LIVE_XAI_OAUTH=1. | 2-3 requests. |
|
|
66
|
+
| `providers/zai` | active | `PRISM_LIVE_PROVIDER_TESTS` + `ZAI_API_KEY` | `PRISM_LIVE_ZAI_MODEL` (default `glm-5.2`) | Z.ai key. | 2 requests. |
|
|
67
|
+
| `web-tools/brave` | active | `PRISM_LIVE_WEB` + `PRISM_BRAVE_SEARCH_TOKEN` | — | Brave Search token, least-privilege plan; 1 result per query. | 1 search request. |
|
|
68
|
+
| `web-tools/exa` | active | `PRISM_LIVE_WEB` + `PRISM_EXA_API_KEY` | — | Exa key; 1 result per query. | 1 search request. |
|
|
69
|
+
| `web-tools/firecrawl` | active | `PRISM_LIVE_WEB` + `PRISM_FIRECRAWL_API_KEY` | — | Firecrawl key; bounded 64 KiB markdown fetch. | 1 fetch request. |
|
|
70
|
+
| `web-tools/browser-live` | active | any of: `PRISM_LIVE_PLAYWRIGHT` / `PRISM_TEST_PLAYWRIGHT` | — | Real Chromium, no secret; needs Playwright browsers installed. | Local browser session, no API spend. |
|
|
71
|
+
| `web-tools/obscura-live` | active | `PRISM_LIVE_OBSCURA` + `PRISM_OBSCURA_BIN` | — | Local obscura CLI binary; suite fails closed if flag set without binary. | Local process, no API spend. |
|
|
72
|
+
| `memory/observational-live` | active | `PRISM_LIVE_OBSERVATIONAL_MEMORY_TESTS` + `OPENAI_API_KEY` | `PRISM_LIVE_OPENAI_MODEL` (not wired yet) | Reuses the OpenAI key as the compaction worker provider. | A few small summarization requests. |
|
|
73
|
+
| `memory/compaction-llm-live` | active | `PRISM_LIVE_COMPACTION_TESTS` | — | Stub leg today: live summary-provider checks are wired by plans/064 Task 6 (provider key + model env TBD there). | n/a until wired. |
|
|
74
|
+
| `office/libreoffice-golden` | active | `PRISM_TEST_LIBREOFFICE` | — | Local LibreOffice binary renders golden documents; no secret. | Local process, no API spend. |
|
|
75
|
+
| `office/drawio-live` | active | any of: `PRISM_LIVE_DRAWIO_URL` / `PRISM_TEST_DRAWIO_URL` | — | Operator-hosted drawio export service URL (not a secret). | 1-2 export requests to your own service. |
|
|
76
|
+
| `core/postgres` | active | `PRISM_TEST_POSTGRES_URL` | — | Throwaway PostgreSQL database URL (sessions + enterprise + event-source + memory vector legs). | Local/container DB, no API spend. |
|
|
77
|
+
| `core/nats` | active | `PRISM_TEST_NATS_URL` | — | NATS server URL with JetStream enabled. | Local/container server, no API spend. |
|
|
78
|
+
| `coding-tools/docker-sandbox` | active | `PRISM_TEST_DOCKER_SANDBOX` + `PRISM_TEST_DOCKER_BIN` + `PRISM_TEST_DOCKER_IMAGE` + `PRISM_TEST_DOCKER_USER` | — | Local Docker daemon + pinned minimal sandbox image; no secret. | Local containers, no API spend. |
|
|
79
|
+
| `core/keychain` | active | `PRISM_TEST_KEYCHAIN` | — | Real OS keychain; writes throwaway test entries only. | Local, no API spend. |
|
|
80
|
+
| `acp/client-smoke` | active | `PRISM_TEST_ACP_CLIENT` | — | Real ACP SDK client over stdio in a subprocess; sandboxed, policy never disabled. | Local process, no API spend. |
|
|
81
|
+
| `canaries/deployed` | active | `PRISM_LIVE_CANARIES`; optional: `PRISM_CANARY_TIMEOUT_MS` `PRISM_CANARY_REPORT` | — | Deployed prism provider/MCP/A2A endpoints; script itself validates all PRISM_CANARY_* URL/token vars and credential-free HTTPS. | 1-4 bounded requests (64 KiB JSON cap) against your deployments. |
|
|
82
|
+
| `providers/azure` | active | `PRISM_LIVE_PROVIDER_TESTS` + `AZURE_OPENAI_ENDPOINT` + `AZURE_OPENAI_API_KEY` + `PRISM_LIVE_AZURE_MODEL` | `PRISM_LIVE_AZURE_MODEL` (default `gpt-5.1`) | Azure OpenAI resource key. | 3-4 requests on the configured deployment. |
|
|
83
|
+
| `providers/bedrock` | active | `PRISM_LIVE_PROVIDER_TESTS` + `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY` + `AWS_REGION` | `PRISM_LIVE_BEDROCK_MODEL` (default `us.anthropic.claude-haiku-4-5-20251001-v1:0`) | AWS access key + secret (SigV4). | 3-4 requests on haiku-class model. |
|
|
84
|
+
| `providers/vertex` | active | `PRISM_LIVE_PROVIDER_TESTS` + `GOOGLE_VERTEX_PROJECT` + `PRISM_VERTEX_ACCESS_TOKEN` | `PRISM_LIVE_VERTEX_MODEL` (default `gemini-2.5-flash`) | Pre-minted Vertex bearer token (e.g. gcloud auth print-access-token). | 3-4 requests on flash-class model. |
|
|
85
|
+
| `providers/ollama` | active | `PRISM_LIVE_PROVIDER_TESTS` + `OLLAMA_BASE_URL` | `PRISM_LIVE_OLLAMA_MODEL` (default `(first model served by OLLAMA_BASE_URL)`) | No credential for local ollama serve; Ollama Cloud key optional via provider options. | 3-4 requests on the first locally pulled model. |
|
|
86
|
+
| `providers/ai-sdk` | active | `PRISM_LIVE_PROVIDER_TESTS` + `OPENAI_API_KEY` | `PRISM_LIVE_AISDK_MODEL` (default `gpt-5.1`) | Reuses OPENAI_API_KEY through the real @ai-sdk/openai provider. | 3 requests on gpt-5.1. |
|
|
87
|
+
| `providers/model-discovery` | active | `PRISM_LIVE_PROVIDER_TESTS`; any of: `OPENAI_API_KEY` / `GEMINI_API_KEY` | — | Reuses OPENAI_API_KEY or GEMINI_API_KEY for a real listing request. | 2 GET /models requests (second cached in TTL). |
|
|
88
|
+
| `cli/live-journey` | planned | `PRISM_LIVE_PROVIDER_TESTS` + `OPENAI_API_KEY` | — | Packed CLI: init/provider-add/print/json/rpc over a real provider; transcript secret-scanned. | 1 pack + install, offline scaffold tests, <=3 wire prompts on the selected provider model (wire legs skip on 401/403). |
|
|
89
|
+
| `memory/rag-rerankers-live` | active | any of: `PRISM_TEST_TEI_RERANKER_URL` / `PRISM_TEST_HOSTED_RERANK_URL`; optional: `PRISM_TEST_HOSTED_RERANK_URL` | `PRISM_LIVE_TEI_RERANKER_MODEL` (default `(endpoint default model)`), `PRISM_LIVE_HOSTED_RERANK_MODEL` (default `(endpoint default model)`) | Real TEI / OpenAI-compatible rerank endpoints; each leg self-skips when its endpoint env is unset. | 1 rerank request per configured endpoint (≤2 total). |
|
|
90
|
+
| `coding-tools/openapi-live` | active | `PRISM_LIVE_OPENAPI_TOOLS` | — | Real public OpenAPI 3.1 spec (warnely.com) + real GET tool calls; no credential. | 3 HTTP requests against example.com-class public hosts (plan budget ≤5). |
|
|
91
|
+
| `coding-tools/computer-use-live` | active | `PRISM_TEST_COMPUTER_USE` + `PRISM_COMPUTER_USE_BIN` | — | Real host computer-use-linux MCP binary over stdio; real tool inventory + one bounded read-only screenshot. | Local desktop only; ≤30s ceiling. |
|
|
92
|
+
| `mcp/client-smoke` | active | `PRISM_TEST_MCP_CLIENT` | — | Real @modelcontextprotocol/client SDK over a real stdio subprocess serving createPrismMcpServer. | Local only; ≤30s. |
|
|
93
|
+
| `core/opa-live` | active | `PRISM_TEST_OPA_URL` | — | Operator-hosted OPA REST endpoint (optionally token-gated). | <=3 decision requests to the operator OPA endpoint; fail-closed probe never reaches the wire. |
|
|
94
|
+
| `core/oidc-live` | active | `PRISM_TEST_OIDC_ISSUER` + `PRISM_TEST_OIDC_AUDIENCE` + `PRISM_TEST_OIDC_TOKEN` | — | Real IdP issuer/JWKS + short-lived test bearer token. | 1 JWKS fetch (cached) + 3 local verify calls; no token endpoint traffic. |
|
|
95
|
+
| `core/webhooks-live` | active | `PRISM_TEST_WEBHOOK_URL` | — | Operator-controlled signed webhook receiver. | <=3 webhook deliveries (1 signed target + 1 loopback retry receiver). |
|
|
96
|
+
| `core/artifact-bodies-s3-live` | active | `PRISM_TEST_S3_ENDPOINT` + `PRISM_TEST_S3_KEY` + `PRISM_TEST_S3_SECRET` + `PRISM_TEST_S3_BUCKET` | — | Dedicated throwaway S3-compatible bucket. | <=5 S3 requests (put/get/presign/delete x2). |
|
|
97
|
+
| `cli/journey` | active | `PRISM_LIVE_PROVIDER_TESTS`; any of: `OPENAI_API_KEY` / `OPENROUTER_API_KEY` / `KIMI_API_KEY` / `ZAI_API_KEY` / `OPENCODE_API_KEY` / `NEURALWATT_API_KEY` / `DASHSCOPE_API_KEY` / `OLLAMA_API_KEY` | — | First init-catalog provider credential present in the environment. | 4-5 one-shot requests on the default catalog model. |
|
|
98
|
+
| `memory/postgres` | active | `PRISM_TEST_POSTGRES_URL` | — | Postgres memory store + pgvector index round-trips on the operator database. | Bounded insert/query cycles against the configured Postgres. |
|
|
99
|
+
| `memory/graft` | active | — (hermetic leg) | — | Graft upstream CLI child-process protocol (real binary spawns against the in-repo fixture graft bin). | Hermetic; no network. |
|
|
100
|
+
| `memory/wiki` | active | — (hermetic leg) | — | Wiki lifecycle over real fs trees (init/refresh/lint/search fallback; qmd child-process client degrades without the binary). | Hermetic; no network. |
|
|
101
|
+
| `coding-tools/lsp-forge` | active | — (hermetic leg) | — | LSP/language-intelligence + forge suites: real child-process spawns over the real LSP/forge wire protocols against fixture binaries. | Hermetic; no network. |
|
|
102
|
+
| `ag-ui/conformance` | active | — (hermetic leg) | — | AG-UI + ACP conformance suites: real-event replay over the acp/a2a/ag-ui protocol surfaces (fixture agents, real event-source wire semantics). | Hermetic; no network. |
|
|
103
|
+
| `prism-providers/conformance` | active | — (hermetic leg) | — | Plan-065 machine-checked thinking coverage: every first-party reasoning catalog model declares capabilities.thinkingLevels + a compat.thinkingFamily stamp and emits a legal effort field on the wire (14 catalogs walked hermetically). | free |
|
|
104
|
+
<!-- generated:live-matrix:end -->
|
|
105
|
+
|
|
106
|
+
## Strict CI workflow
|
|
107
|
+
|
|
108
|
+
The scheduled [`live-canaries` workflow](../.github/workflows/live-canaries.yml) (Tuesdays 05:43 UTC, plus `workflow_dispatch`) runs four restricted protocol canaries — provider, MCP, A2A, and Brave search — from a GitHub `live-canaries` environment, with every value supplied through repository secrets and a 15 s per-canary timeout. It runs `scripts/live-canary.mjs` (gated on `PRISM_LIVE_CANARIES=1`, which requires **all** canary credentials together so A2A never runs standalone) and uploads the status report as a workflow artifact. The full live matrix runs on a weekly schedule (and on demand) via the [`live-matrix` workflow](../.github/workflows/live-matrix.yml): strict-mode filtered run (default `providers/opencode-go`, the credentialed suites) with the report + e2e-coverage evidence uploaded as artifacts; operators also run it from a credentialed checkout with `npm run test:live`, optionally `PRISM_LIVE_STRICT=1` when gating a release.
|
|
109
|
+
|
|
110
|
+
## Security and performance notes
|
|
111
|
+
|
|
112
|
+
- Credentials never enter the repo, test fixtures, logs, or reports; only env var names and model ids are persisted. `assertNoSecretLeak` (exported from `@arnilo/prism/testing/*`) runs over live transcripts, and secret-shaped values in `scripts/live-matrix.json` are rejected by the manifest validator.
|
|
113
|
+
- Suite costs are bounded and recorded per row; provider model defaults are the cheapest cost-bounded models that satisfy each probe.
|
|
114
|
+
- Per-suite `PRISM_LIVE_SUITE_TIMEOUT_MS` kill timers and opt-in `PRISM_LIVE_CONCURRENCY` parallelism keep a stuck wire from stalling the run.
|
|
115
|
+
- Packaging tests run under `scripts/with-build-lock.mjs` so parallel suites never race the TypeScript build.
|
|
116
|
+
|
|
117
|
+
## Extension and configuration notes
|
|
118
|
+
|
|
119
|
+
- Add a suite: write the env-gated test (skip-not-fail), register it in `scripts/live-matrix.json` (`id`, `package`, `status`, `source`, `command`, `cwd`, `requires`/`requiresAny`, model wiring, least-privilege `scope`, `cost`), then run `node scripts/generate-live-docs.mjs --write` to refresh the table above. `scripts/live-doc-check.test.mjs` fails `npm test` when the doc drifts.
|
|
120
|
+
- Add a credential: extend `scripts/live.env.example` and the relevant manifest `requires` list. Prefer `requiresAny` when a probe accepts several interchangeable providers.
|
|
121
|
+
|
|
122
|
+
## Related APIs
|
|
123
|
+
|
|
124
|
+
- `@arnilo/prism/testing/*` conformance helpers (`assertProviderStreamConforms`, `assertNoSecretLeak`): the assertion vocabulary live suites reuse.
|
|
125
|
+
- `scripts/e2e-coverage-gate.mjs` + `scripts/e2e-coverage.json`: the functional-surface coverage ledger this matrix satisfies.
|
|
126
|
+
- [Provider conformance](provider-conformance.md): the network-free contract checks every provider adapter must pass before a live suite is worth running.
|
package/docs/mcp-tools.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## What it does
|
|
4
4
|
|
|
5
|
-
`@arnilo/prism-mcp` has two explicit directions. Its client bridge connects hosts to remote [Model Context Protocol](https://modelcontextprotocol.io) servers and maps discovered tools to ordinary `ToolDefinition`s. Its server API registers selected Prism `ToolDefinition` and `CommandDefinition` values on the official SDK `McpServer`, with required authorization and a bounded optional Web-standard Streamable HTTP handler. The package pins `@modelcontextprotocol/
|
|
5
|
+
`@arnilo/prism-mcp` has two explicit directions. Its client bridge connects hosts to remote [Model Context Protocol](https://modelcontextprotocol.io) servers and maps discovered tools to ordinary `ToolDefinition`s. Its server API registers selected Prism `ToolDefinition` and `CommandDefinition` values on the official SDK `McpServer`, with required authorization and a bounded optional Web-standard Streamable HTTP handler. The package pins the modular TypeScript SDK v2 packages `@modelcontextprotocol/client` and `@modelcontextprotocol/server` **2.0.0** (MCP protocol negotiation remains SDK-owned; the 2026-07-28 adoption is tracked in plan 063) and adds no MCP branch to core Prism.
|
|
6
6
|
|
|
7
7
|
Primary API:
|
|
8
8
|
|
|
@@ -32,19 +32,25 @@ const app = await bridge.apps!.readResource("ui://weather/card");
|
|
|
32
32
|
|
|
33
33
|
`bridge.apps` exposes reviewed UI metadata, linked bounded `ui://` HTML, and same-server app tools for a host renderer/proxy; it never creates an iframe or executes HTML.
|
|
34
34
|
|
|
35
|
+
**Conformance and verification record (plan 063 task 7):** the official `@modelcontextprotocol/conformance` suite runs against the dual-era serving stack via `node scripts/mcp-conformance-2026.mjs` — the 20 expressible scenarios pass and the 14 scenarios requiring surface Prism does not expose (server-initiated sampling/elicitation/logging/progress from tool callbacks, `resources/subscribe`, completion capability, session-based SSE polling, non-text tool content blocks) are recorded as documented boundaries in `scripts/mcp-conformance-2026-baseline.yaml`. The CLI publishes scenarios only up to spec version 2025-11-25; the run is repeated when 2026-07-28 scenarios ship upstream. Measured on the loopback fixture (single process): legacy connect ~60ms, auto connect (with the one discovery probe) ~40ms, pinned modern connect ~20ms, steady-state bridge tool call ~4ms, uncached list walk ~5ms, cached list refresh ~2ms — the only added connect cost versus 1.x is the single negotiation probe plus SDK codec work. Security regression coverage lives in the package suites: malformed envelopes/headers, auth mix-up (`ERR_PRISM_MCP_OAUTH_ORIGIN`), SSRF/DNS-rebinding, oversized JSON/schema/results, MRTR round/replay, subscription exhaustion caps, cross-principal cache/session isolation, timeouts, cancellation, and redaction.
|
|
36
|
+
|
|
37
|
+
**Extension status (revalidated 2026-09-05 against the modular SDK v2, plan 063 task 6):** MCP Apps (`io.modelcontextprotocol/ui`) is the only extension Prism negotiates — on both the 2025 legacy handshake and 2026-07-28 (modern capabilities ride per request in `params._meta`); resource reads/pagination now go through SDK v2 `listResources`/`readResource` with the same per-descriptor byte bounds, item caps, cursor-loop detection, and linked-HTML validation as before. **Tasks (`io.modelcontextprotocol/tasks`) is intentionally not advertised and not supported in this release**: neither the bridge client nor `createPrismMcpServer` declares it, draft-era `task` members on tool results fail closed (`McpBridgeError` surfaced as a `ToolResult.error`, never read as tool output; modern `resultType: "task"` fails SDK decode), and task handles are not accepted without a supported extension codec plus a durable ownership model. Re-evaluate Tasks when the official TypeScript client/server extension codec supports task result dispatch, polling/update/cancel, and subscription notifications with green conformance.
|
|
38
|
+
|
|
35
39
|
```ts
|
|
36
40
|
const bridge = await connectMcpCapabilities({
|
|
37
41
|
serverId: "research",
|
|
38
42
|
transport: { type: "streamable-http", url, allowedOrigins: [origin] },
|
|
39
|
-
roots: () => [{ uri: "file:///workspace", name: "workspace" }],
|
|
40
|
-
sampling: hostSampling, //
|
|
41
|
-
elicitation: hostElicitation, // URL mode returns approval; Prism never opens/fetches URL
|
|
43
|
+
roots: () => [{ uri: "file:///workspace", name: "workspace" }], // deprecated: kept for legacy callers only
|
|
44
|
+
sampling: hostSampling, // deprecated: kept for legacy callers only
|
|
45
|
+
elicitation: hostElicitation, // active; URL mode returns approval; Prism never opens/fetches URL
|
|
42
46
|
});
|
|
43
47
|
await bridge.listResources();
|
|
44
48
|
await bridge.getPrompt("review", { topic: "security" });
|
|
45
49
|
```
|
|
46
50
|
|
|
47
|
-
|
|
51
|
+
Roots and sampling callbacks are **deprecated with MCP 2026-07-28 (SEP-2577)** and kept only for existing legacy callers; Synapta adds nothing on those surfaces and they may be removed when the protocol revision does (earliest per spec: a revision released on or after 2027-07-28). Elicitation is the active capability: on the modern era a server answering a tool call with `input_required` is fulfilled by the SDK's MRTR driver against the same `elicitation` callback, capped by `maxMrtrRounds` (default 10, the SDK's own bound — the option can only tighten it) with the call timeout as the outer ceiling; on the legacy era the same handler serves direct `elicitation/create` requests. `humanInteraction: true` remains mandatory for accepted elicitation, and no hand-written retry/state machinery exists on either path.
|
|
52
|
+
|
|
53
|
+
Server capability matrix for the modular TypeScript SDK v2 (`@modelcontextprotocol/client` + `@modelcontextprotocol/server` 2.0.0): tools/resources/prompts and their list-change notifications are supported through official registrations; roots/sampling/form+URL elicitation are supported as explicit client callbacks. Missing server resources/prompts throw `McpUnsupportedCapabilityError` with `ERR_PRISM_MCP_UNSUPPORTED_CAPABILITY`. Resource/prompt results and sampling/elicitation inputs/results are bounded JSON. Accepted form/URL elicitation requires host-only `humanInteraction: true`; bridge strips marker before protocol output and fails closed when absent. Automatic root discovery/consent, model selection, credential resolution, URL navigation, generic command proxying, and custom JSON-RPC are unsupported.
|
|
48
54
|
|
|
49
55
|
Server direction:
|
|
50
56
|
|
|
@@ -66,18 +72,22 @@ const handleMcp = await createPrismMcpWebHandler(server, {
|
|
|
66
72
|
resolveAuthInfo: authenticateRequest,
|
|
67
73
|
allowedHosts: ["api.example.test"],
|
|
68
74
|
allowedOrigins: ["https://app.example.test"],
|
|
69
|
-
// Omit these two for
|
|
75
|
+
// Omit these two for dual-era serving without legacy sessions.
|
|
70
76
|
sessionIdGenerator: crypto.randomUUID,
|
|
71
77
|
resolveIdentity: (_request, auth) => auth ? { id: validatedPrincipalId(auth) } : false,
|
|
72
78
|
});
|
|
73
79
|
```
|
|
74
80
|
|
|
75
|
-
`
|
|
81
|
+
`createPrismMcpWebHandler()` is dual-era on the modular SDK v2 serving entries. Default (factory, no `sessionIdGenerator`): modern 2026-07-28 serving through SDK `createMcpHandler` — one fresh `McpServer` per request, SDK-generated `server/discover`, result metadata, cancellation and modern headers — with the SDK stateless fallback answering 2025-era traffic; modern responses carry no `Mcp-Session-Id`. Supplying `sessionIdGenerator` keeps documented legacy `MCP-Session-Id` POST/GET/DELETE/SSE lifecycle on a sessionful `WebStandardStreamableHTTPServerTransport` beside a strict modern handler (classified legacy traffic routes separately), and still requires exact `allowedOrigins` plus host `resolveIdentity`; every request re-authenticates, and a different principal receives non-disclosing 404. `Last-Event-ID` replay remains explicitly unsupported.
|
|
82
|
+
|
|
83
|
+
Security gates run in front of the SDK entries because `createMcpHandler` intentionally provides none: exact Host/Origin allowlist checks execute before body parsing, auth, and dispatch; bounded body parsing feeds `parsedBody`; verified `AuthInfo` is passed explicitly; authorization and identity checks run on every request; modern serving state never trusts a transport session id. A bare `McpServer` instance with sessions keeps legacy-only behavior; stateless mode requires a factory (one fresh server per request). The returned value stays callable and carries SDK lifecycle properties: `fetch` (same function), `close()` (tears down both eras), `notify.toolsChanged()/promptsChanged()/resourcesChanged()/resourceUpdated(uri)`, and `bus` for `subscriptions/listen`. `maxSubscriptions` (SDK default 1024) and `keepAliveMs` (SDK default 15000, 0 disables) bound modern subscription streams.
|
|
84
|
+
|
|
85
|
+
`servePrismMcpStdio(factory, options)` serves dual-era stdio: the opening exchange pins the era (one factory instance per connection; `legacy: "serve"` default keeps 2025 openings working, `"reject"` answers them with the unsupported-protocol-version error), and stdout stays protocol-only. `McpServer.connect(transport)` remains available for in-memory transports; direct `server.connect()` over HTTP is legacy-only. `createPrismMcpServer({ cacheHints })` emits SEP-2549 cache hints on cacheable 2026-07-28 results (default `ttlMs: 0`, `private`). Neither HTTP nor stdio helper starts a listener or process lifecycle for you.
|
|
76
86
|
|
|
77
87
|
## When to use it
|
|
78
88
|
|
|
79
89
|
- **Integrate external MCP tool servers** (filesystem, databases, SaaS adapters) without reimplementing JSON-RPC transports in your app.
|
|
80
|
-
- **Bridge a specific upstream server through a reviewed adapter** — e.g. the optional [`@arnilo/prism-obscura`](obscura.md) wraps `connectMcpTools` with Obscura-specific command validation and conservative effect classification for the complete advertised tool surface.
|
|
90
|
+
- **Bridge a specific upstream server through a reviewed adapter** — e.g. the optional [`@arnilo/prism-web-tools/obscura`](obscura.md) subpath wraps `connectMcpTools` with Obscura-specific command validation and conservative effect classification for the complete advertised tool surface.
|
|
81
91
|
- **Keep core dispatch gates** — register returned tools and let `dispatchToolCall` enforce permission, JSON Schema validation (`ToolValidator`), middleware, abort, and parallel execution (Plan 055 Tasks 1–2).
|
|
82
92
|
- **Explicit lifecycle** — connect, refresh on `notifications/tools/list_changed`, and `close()` when the session ends.
|
|
83
93
|
- **Expose selected capabilities** — register a reviewed tool/command allow-list for MCP clients without a custom JSON-RPC server.
|
|
@@ -92,7 +102,7 @@ Do **not** use this package as a sandbox, permission engine, or auto-discovery l
|
|
|
92
102
|
|
|
93
103
|
`McpToolBridge` exposes `tools`, optional `apps`, `refresh()`, and `close()`. Normal tools are Prism `ToolDefinition`s. Apps requires server acknowledgement; nested resource metadata wins over flat/deprecated and app-only tools stay outside `tools`. Resource reads require linked bounded `ui://` HTML5 with exact MIME; content metadata wins over list defaults.
|
|
94
104
|
|
|
95
|
-
`createPrismMcpServer()` returns the SDK `McpServer`. It lists only passed tools/commands and explicitly selected `agentRuns` lifecycle tools; JSON Schema parameters are converted through installed Zod v4 for SDK validation, then Prism tool calls still pass through `dispatchToolCall` permission/validator/redactor gates. Command definitions support explicitly selected direct/background/replay workflow operations and optional ownership-scoped schedule operations from `createWorkflowCommands()`; none are registered unless the host passes those command definitions. Calls return bounded MCP text content and `isError` on denial/failure. `createPrismMcpWebHandler()`
|
|
105
|
+
`createPrismMcpServer()` returns the SDK `McpServer`. It lists only passed tools/commands and explicitly selected `agentRuns` lifecycle tools; JSON Schema parameters are converted through installed Zod v4 for SDK validation, then Prism tool calls still pass through `dispatchToolCall` permission/validator/redactor gates. Command definitions support explicitly selected direct/background/replay workflow operations and optional ownership-scoped schedule operations from `createWorkflowCommands()`; none are registered unless the host passes those command definitions. Calls return bounded MCP text content and `isError` on denial/failure. `createPrismMcpWebHandler()` remains callable for source compatibility and additionally carries `fetch`, `close`, `notify`, and `bus` from the SDK serving entry.
|
|
96
106
|
|
|
97
107
|
## Request/response example
|
|
98
108
|
|
|
@@ -241,15 +251,27 @@ import { createMcpClientAuth } from "@arnilo/prism-mcp";
|
|
|
241
251
|
const auth = createMcpClientAuth(
|
|
242
252
|
{
|
|
243
253
|
state, // required persistence seam: load/save tokens, discovery, client info, code verifier
|
|
244
|
-
strategy: { kind: "
|
|
254
|
+
strategy: { kind: "cimd", clientMetadataUrl: "https://client.example/oauth/metadata.json" }, // preferred
|
|
255
|
+
// or { kind: "static", clientId: "prism", clientSecret: "..." }
|
|
256
|
+
// or { kind: "dcr", clientMetadata } — deprecated (RFC 7591), application_type defaults to "native"
|
|
245
257
|
redirectUri: "http://localhost:33418/callback",
|
|
246
258
|
onRedirectRequired: (url) => openBrowser(url), // interactive flows
|
|
259
|
+
onInsufficientScope: "reauthorize", // or "throw" to surface SDK InsufficientScopeError instead
|
|
247
260
|
},
|
|
248
261
|
{ serverUrl: "https://mcp.example.com/api", fetch },
|
|
249
262
|
);
|
|
250
263
|
```
|
|
251
264
|
|
|
252
|
-
The flow reuses the MCP SDK's `auth()` helper (401 → protected-resource metadata → RFC 8414 discovery → PKCE S256 → token exchange/refresh) wrapped in Prism policy: discovery URLs are SSRF-checked, https-only (loopback http opt-in), DNS-pinned, zero-redirect, and byte-bounded; RFC 8707 resource binding is enforced on every token request (`ERR_PRISM_MCP_OAUTH_AUDIENCE` on origin drift); issuer origin must match the discovered authorization server (`ERR_PRISM_MCP_OAUTH_ORIGIN`); bearer tokens are only ever attached to the allow-listed server origin.
|
|
265
|
+
The flow reuses the MCP SDK's `auth()` helper (401 → protected-resource metadata → RFC 8414 discovery → PKCE S256 → token exchange/refresh) wrapped in Prism policy: discovery URLs are SSRF-checked, https-only (loopback http opt-in), DNS-pinned, zero-redirect, and byte-bounded; RFC 8707 resource binding is enforced on every token request (`ERR_PRISM_MCP_OAUTH_AUDIENCE` on origin drift); issuer origin must match the discovered authorization server (`ERR_PRISM_MCP_OAUTH_ORIGIN`); bearer tokens are only ever attached to the allow-listed server origin.
|
|
266
|
+
|
|
267
|
+
2026-07-28 authorization conformance (plan 063 task 5):
|
|
268
|
+
|
|
269
|
+
- **Callback completion takes the full query**: `await auth.finishAuth(new URL(callbackUrl).searchParams)`. The persisted OAuth `state` is validated first (fail-closed `ERR_PRISM_MCP_OAUTH_STATE` when absent or mismatched), then the RFC 9207 `iss` parameter is checked against the persisted authorization server; the SDK independently validates `iss` against the recorded issuer (RFC 9207 §2.4) and the callback-leg AS binding (SEP-2352) before redeeming the code. Callback `error`/`error_description` fields are never surfaced after an issuer mismatch. A bare code string is accepted as the legacy form (no state/iss validation).
|
|
270
|
+
- **Issuer-keyed credential storage**: persisted token/client records are SDK issuer-stamped (`StoredOAuthTokens`/`StoredOAuthClientInformation`); `McpClientAuthState` credential methods take the validated `issuer` so partitioned stores can key on it. Records stamped for a different issuer are never served, and ambiguous un-stamped pre-upgrade records are refused on issuer-keyed reads rather than guessed — re-authorization runs once and every persisted record is stamped thereafter.
|
|
271
|
+
- **Registration strategy**: CIMD (SEP-991 URL-based client ids) is preferred, `static` remains supported, and `dcr` is deprecated; the DCR metadata defaults `application_type` to `"native"` when the host omits it.
|
|
272
|
+
- **Insufficient-scope policy**: `onInsufficientScope: "reauthorize"` (default) runs the SDK's bounded step-up flow; `"throw"` surfaces the typed SDK `InsufficientScopeError` (with the challenge scope) instead of redirecting. Hosts gate interactive consent either way.
|
|
273
|
+
|
|
274
|
+
`McpClientAuthState` has no default implementation — production hosts back it with an encrypted/keychain store (refresh tokens must not live in plaintext persistence).
|
|
253
275
|
|
|
254
276
|
**Server** — advertise protected-resource metadata and challenge unauthenticated requests:
|
|
255
277
|
|
|
@@ -264,12 +286,22 @@ const handler = await createPrismMcpWebHandler(factory, {
|
|
|
264
286
|
});
|
|
265
287
|
```
|
|
266
288
|
|
|
267
|
-
The handler serves `GET /.well-known/oauth-protected-resource` and returns `401 WWW-Authenticate: Bearer resource_metadata="<origin>/.well-known/oauth-protected-resource"` on rejected requests. Token verification remains entirely host-owned via `resolveIdentity
|
|
289
|
+
The handler serves `GET /.well-known/oauth-protected-resource` and returns `401 WWW-Authenticate: Bearer resource_metadata="<origin>/.well-known/oauth-protected-resource", scope="<configured scopes>"` on rejected requests. Token verification remains entirely host-owned via `resolveIdentity` — the host token verifier must validate the token audience (`aud`) against the protected resource and enforce the challenged scopes; Prism only advertises and challenges.
|
|
268
290
|
|
|
269
291
|
## Vendor web MCP prototype boundary
|
|
270
292
|
|
|
271
293
|
Official Exa/Firecrawl MCP servers may be tested only as explicit hardened prototypes: pin endpoint/origin/auth, inspect declared capabilities, allow-list individual tools/resources, retain all MCP bounds, and never expose generic remote passthrough. Production web research uses direct host-selected `@arnilo/prism-web-tools` adapters so provider choice, credentials, schema, and costs remain outside model control.
|
|
272
294
|
|
|
295
|
+
## Real-client smoke (plans/064 Task 8)
|
|
296
|
+
|
|
297
|
+
An operator-gated smoke drives `createPrismMcpServer` through the real `@modelcontextprotocol/client` SDK over a real stdio subprocess — the same shape a production MCP host uses:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
PRISM_TEST_MCP_CLIENT=1 node scripts/mcp-client-smoke.mjs
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
The scenario stays sandboxed (read-only echo tool, authorize-gated denial, no policy bypass) and covers: modern auto + legacy handshakes, `tools/list` of registered capabilities, `tools/call` round-trip, the authorize gate enforced over the wire, and malformed-frame fail-closed (the transport tears the connection down instead of answering garbage). Server-initiated `elicitation/create` is a documented Prism boundary (`scripts/mcp-conformance-2026-baseline.yaml`); the bridge-side MRTR elicitation round-trip is covered over real HTTP by the package's modern-bridge tests. Registered in `scripts/live-matrix.json` as `mcp/client-smoke`.
|
|
304
|
+
|
|
273
305
|
## Related APIs
|
|
274
306
|
|
|
275
307
|
- [Agent identity](agent-identity.md): optional verified identity on MCP authorize results
|
|
@@ -278,7 +310,6 @@ Official Exa/Firecrawl MCP servers may be tested only as explicit hardened proto
|
|
|
278
310
|
- [Tool execution primitives](tool-execution-primitives.md): Plan 055 design and conformance matrix
|
|
279
311
|
- [Host security guide](host-security.md): permission, trust, validation checklist
|
|
280
312
|
- [Web-standard server handler](server.md): agent/workflow HTTP routes and shared remote-boundary rules
|
|
281
|
-
- [Antigravity delegated agent](antigravity-agent.md): per-run loopback HTTP MCP server exposure for the official Antigravity CLI.
|
|
282
313
|
- [ACP coding-host interop](acp.md): ACP clients may attach MCP servers to sessions — bounded configs (8/32 servers, 16 KiB/256 KiB config, 4 KiB/64 KiB header values), http/sse only when advertised, stdio accepted behind the gate, UNSTABLE `acp` always rejected, and every server approved by host `mcp.select` before the bridge connects.
|
|
283
314
|
|
|
284
315
|
## Testing
|
package/docs/middleware-hooks.md
CHANGED
|
@@ -101,7 +101,7 @@ export const extension: Extension = {
|
|
|
101
101
|
- `retry` middleware may stop retrying or adjust delay, but runtime still owns retry event emission, abort-aware waiting, and provider-turn boundaries.
|
|
102
102
|
- The registry does not discover packages, read manifests, load config, call providers, execute tools, read resources, or start sessions.
|
|
103
103
|
- Hosts may pass a middleware registry into `createExtensionKernel({ middleware })` to share it with direct host code.
|
|
104
|
-
- For OpenTelemetry export, prefer `session.subscribe()` + `@arnilo/prism-observability
|
|
104
|
+
- For OpenTelemetry export, prefer `session.subscribe()` + `@arnilo/prism-core/governance/observability` (see [Observability](observability.md)) rather than adding a parallel event bus. Middleware hooks remain for transforming payloads at named boundaries.
|
|
105
105
|
|
|
106
106
|
## Security and performance notes
|
|
107
107
|
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# Migrate legacy 0.3 packages to Prism 0.4
|
|
2
|
+
|
|
3
|
+
> **Status: 0.4 release draft.** Follow this guide only after the 0.4 packages are published.
|
|
4
|
+
> Until then, stay on your current 0.3.x package set. This page is the permanent destination of
|
|
5
|
+
> npm's legacy-package warnings.
|
|
6
|
+
|
|
7
|
+
## What changes
|
|
8
|
+
|
|
9
|
+
Prism 0.4 replaces 62 separate 0.3 package manifests with 10 active packages and explicit
|
|
10
|
+
subpaths. The code and behavior move; this is not a database/data migration. It is a **package
|
|
11
|
+
name and import-specifier migration**.
|
|
12
|
+
|
|
13
|
+
- Existing applications pinned to 0.3.x continue to work.
|
|
14
|
+
- Retired packages are not unpublished. Their final release remains on npm with its `latest`
|
|
15
|
+
tag and gains a `legacy` tag plus an install-time deprecation warning.
|
|
16
|
+
- `npm install` cannot automatically replace one package name with another. Upgrade each package
|
|
17
|
+
dependency and its imports together.
|
|
18
|
+
- There are no 0.4 compatibility wrappers. New packages never import old package names, so the
|
|
19
|
+
package graph cannot form a wrapper cycle.
|
|
20
|
+
- `@arnilo/prism` stays small and dependency-free. Runtime, sessions, governance, and optional
|
|
21
|
+
drivers live in `@arnilo/prism-core`, not root-package subpaths.
|
|
22
|
+
|
|
23
|
+
## Before you start
|
|
24
|
+
|
|
25
|
+
1. Commit or lock your working 0.3.x application.
|
|
26
|
+
2. Record installed Prism packages and direct imports:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm ls --all @arnilo/prism @arnilo/prism-*
|
|
30
|
+
rg -n 'from "@arnilo/prism|import\("@arnilo/prism' src test
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
3. Classify each package using the tables below. Leave unchanged interop packages in place.
|
|
34
|
+
4. Upgrade package dependencies and imports in one pull request; then run your normal typecheck,
|
|
35
|
+
tests, and packed-install smoke test.
|
|
36
|
+
5. Add optional peers only for subpaths you use. Do not add a database, browser, parser, or host
|
|
37
|
+
binary merely because a family package is installed.
|
|
38
|
+
|
|
39
|
+
## Active 0.4 packages
|
|
40
|
+
|
|
41
|
+
| Package | Use it for |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `@arnilo/prism` | Contracts, agent APIs, CLI, root `node/*` and `testing/*` exports. |
|
|
44
|
+
| `@arnilo/prism-core` | Runtime, sessions, governance, credentials, persistence, work integration, JSON Schema validation. |
|
|
45
|
+
| `@arnilo/prism-providers` | All first-party provider adapters as explicit subpaths. |
|
|
46
|
+
| `@arnilo/prism-coding-tools` | Coding agent/security, document reader, OpenAPI, desktop control, Dev inspector, Caveman, Ponytail, Impeccable. |
|
|
47
|
+
| `@arnilo/prism-web-tools` | Generic web tools plus browser and Obscura subpaths. |
|
|
48
|
+
| `@arnilo/prism-memory` | Memory, RAG, compaction, Graft, Wiki. |
|
|
49
|
+
| `@arnilo/prism-office` | Documents, sheets, and diagrams. |
|
|
50
|
+
| `@arnilo/prism-mcp` | MCP interop. |
|
|
51
|
+
| `@arnilo/prism-acp-agent` | ACP interop. |
|
|
52
|
+
| `@arnilo/prism-ag-ui` | AG-UI/A2A/A2UI interop. |
|
|
53
|
+
|
|
54
|
+
`@arnilo/prism-antigravity-agent` has no 0.4 successor. Remove it and keep delegated CLI execution in the host, composed through generic process, tool, MCP, or A2A contracts as needed.
|
|
55
|
+
|
|
56
|
+
## Package and import mapping
|
|
57
|
+
|
|
58
|
+
Replace the package name in `package.json` and every corresponding source import. The tables map
|
|
59
|
+
root package entrypoints. Any documented non-root entrypoint keeps its feature suffix under the
|
|
60
|
+
new family path; the 0.4 API page for that family is authoritative for exact nested exports.
|
|
61
|
+
|
|
62
|
+
### Providers
|
|
63
|
+
|
|
64
|
+
Install `@arnilo/prism-providers` once, then import only the provider subpath used by the host.
|
|
65
|
+
|
|
66
|
+
| Legacy 0.3 package | 0.4 import |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `@arnilo/prism-provider-ai-sdk` | `@arnilo/prism-providers/ai-sdk` |
|
|
69
|
+
| `@arnilo/prism-provider-alibaba` | `@arnilo/prism-providers/alibaba` |
|
|
70
|
+
| `@arnilo/prism-provider-anthropic` | `@arnilo/prism-providers/anthropic` |
|
|
71
|
+
| `@arnilo/prism-provider-azure` | `@arnilo/prism-providers/azure` |
|
|
72
|
+
| `@arnilo/prism-provider-bedrock` | `@arnilo/prism-providers/bedrock` |
|
|
73
|
+
| `@arnilo/prism-provider-clinepass` | `@arnilo/prism-providers/clinepass` |
|
|
74
|
+
| `@arnilo/prism-provider-deepseek` | `@arnilo/prism-providers/deepseek` |
|
|
75
|
+
| `@arnilo/prism-provider-google` | `@arnilo/prism-providers/google` |
|
|
76
|
+
| `@arnilo/prism-provider-kimi` | `@arnilo/prism-providers/kimi` |
|
|
77
|
+
| `@arnilo/prism-provider-neuralwatt` | `@arnilo/prism-providers/neuralwatt` |
|
|
78
|
+
| `@arnilo/prism-provider-ollama` | `@arnilo/prism-providers/ollama` |
|
|
79
|
+
| `@arnilo/prism-provider-openai` | `@arnilo/prism-providers/openai` |
|
|
80
|
+
| `@arnilo/prism-provider-opencode-go` | `@arnilo/prism-providers/opencode-go` |
|
|
81
|
+
| `@arnilo/prism-provider-openrouter` | `@arnilo/prism-providers/openrouter` |
|
|
82
|
+
| `@arnilo/prism-provider-vertex` | `@arnilo/prism-providers/vertex` |
|
|
83
|
+
| `@arnilo/prism-provider-xai` | `@arnilo/prism-providers/xai` |
|
|
84
|
+
| `@arnilo/prism-provider-zai` | `@arnilo/prism-providers/zai` |
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
// Before
|
|
88
|
+
import * as openai from "@arnilo/prism-provider-openai";
|
|
89
|
+
|
|
90
|
+
// After
|
|
91
|
+
import * as openai from "@arnilo/prism-providers/openai";
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Runtime, sessions, governance, and work integration
|
|
95
|
+
|
|
96
|
+
Install `@arnilo/prism-core`, then choose the specific subpath. This family does not add
|
|
97
|
+
optional drivers to your host automatically.
|
|
98
|
+
|
|
99
|
+
| Legacy 0.3 package | 0.4 import |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `@arnilo/prism-server` | `@arnilo/prism-core/runtime/server` |
|
|
102
|
+
| `@arnilo/prism-supervisor` | `@arnilo/prism-core/runtime/supervisor` |
|
|
103
|
+
| `@arnilo/prism-workflows` | `@arnilo/prism-core/runtime/workflows` |
|
|
104
|
+
| `@arnilo/prism-session-store-codecs` | `@arnilo/prism-core/sessions/codecs` |
|
|
105
|
+
| `@arnilo/prism-session-store-nats` | `@arnilo/prism-core/sessions/nats` |
|
|
106
|
+
| `@arnilo/prism-session-store-postgres` | `@arnilo/prism-core/sessions/postgres` |
|
|
107
|
+
| `@arnilo/prism-session-store-sqlite` | `@arnilo/prism-core/sessions/sqlite` |
|
|
108
|
+
| `@arnilo/prism-policy` | `@arnilo/prism-core/governance/policy` |
|
|
109
|
+
| `@arnilo/prism-evals` | `@arnilo/prism-core/governance/evals` |
|
|
110
|
+
| `@arnilo/prism-prompts` | `@arnilo/prism-core/governance/prompts` |
|
|
111
|
+
| `@arnilo/prism-model-router` | `@arnilo/prism-core/governance/model-router` |
|
|
112
|
+
| `@arnilo/prism-observability-opentelemetry` | `@arnilo/prism-core/governance/observability` |
|
|
113
|
+
| `@arnilo/prism-credentials-node` | `@arnilo/prism-core/credentials/node` |
|
|
114
|
+
| `@arnilo/prism-enterprise-postgres` | `@arnilo/prism-core/enterprise/postgres` |
|
|
115
|
+
| `@arnilo/prism-work-tools` | `@arnilo/prism-core/integrations/work` |
|
|
116
|
+
| `@arnilo/prism-tool-validator-json-schema` | `@arnilo/prism-core/validation/json-schema` |
|
|
117
|
+
|
|
118
|
+
`work-tools` belongs to core because enterprise Postgres composes its work-idempotency store.
|
|
119
|
+
It is not part of coding tools.
|
|
120
|
+
|
|
121
|
+
### Coding tools and personas
|
|
122
|
+
|
|
123
|
+
Install `@arnilo/prism-coding-tools`; import the smallest needed subpath. The `prism-dev` binary
|
|
124
|
+
continues to be named `prism-dev` after migration.
|
|
125
|
+
|
|
126
|
+
| Legacy 0.3 package | 0.4 import |
|
|
127
|
+
|---|---|
|
|
128
|
+
| `@arnilo/prism-coding-agent` | `@arnilo/prism-coding-tools/agent` |
|
|
129
|
+
| `@arnilo/prism-coding-security` | `@arnilo/prism-coding-tools/security` |
|
|
130
|
+
| `@arnilo/prism-document-reader` | `@arnilo/prism-coding-tools/document-reader` |
|
|
131
|
+
| `@arnilo/prism-openapi-tools` | `@arnilo/prism-coding-tools/openapi` |
|
|
132
|
+
| `@arnilo/prism-computer-use-linux` | `@arnilo/prism-coding-tools/computer-use-linux` |
|
|
133
|
+
| `@arnilo/prism-dev` | `@arnilo/prism-coding-tools/dev` |
|
|
134
|
+
| `@arnilo/prism-caveman` | `@arnilo/prism-coding-tools/caveman` |
|
|
135
|
+
| `@arnilo/prism-ponytail` | `@arnilo/prism-coding-tools/ponytail` |
|
|
136
|
+
| `@arnilo/prism-impeccable` | `@arnilo/prism-coding-tools/impeccable` |
|
|
137
|
+
|
|
138
|
+
### Web, browser, and Obscura
|
|
139
|
+
|
|
140
|
+
`@arnilo/prism-web-tools` keeps its root entrypoint for generic research tools. Browser and
|
|
141
|
+
Obscura become explicit subpaths; neither activates a browser or process on import.
|
|
142
|
+
|
|
143
|
+
| Legacy 0.3 package | 0.4 import |
|
|
144
|
+
|---|---|
|
|
145
|
+
| `@arnilo/prism-browser` | `@arnilo/prism-web-tools/browser` |
|
|
146
|
+
| `@arnilo/prism-obscura` | `@arnilo/prism-web-tools/obscura` |
|
|
147
|
+
|
|
148
|
+
### Memory, RAG, compaction, and context
|
|
149
|
+
|
|
150
|
+
`@arnilo/prism-memory` retains its root memory entrypoint and gains explicit subpaths. The
|
|
151
|
+
`prism-wiki` binary remains named `prism-wiki` and continues to ship Wiki skills.
|
|
152
|
+
|
|
153
|
+
| Legacy 0.3 package | 0.4 import or install |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `@arnilo/prism-rag` | `@arnilo/prism-memory/rag` |
|
|
156
|
+
| `@arnilo/prism-compaction-llm` | `@arnilo/prism-memory/compaction/llm` |
|
|
157
|
+
| `@arnilo/prism-compaction-observational-memory` | `@arnilo/prism-memory/compaction/observational-memory` |
|
|
158
|
+
| `@arnilo/prism-graft` | `@arnilo/prism-memory/graft` |
|
|
159
|
+
| `@arnilo/prism-wiki` | `@arnilo/prism-memory/wiki` |
|
|
160
|
+
| `@arnilo/prism-compaction` | Install `@arnilo/prism-memory`; choose one or both compaction subpaths. No direct import replacement: it was a profile-only manifest. |
|
|
161
|
+
|
|
162
|
+
### Office suite
|
|
163
|
+
|
|
164
|
+
Plans 051–053 drafted three separate packages. They were never published to npm.
|
|
165
|
+
Install `@arnilo/prism-office` and import the subpath:
|
|
166
|
+
|
|
167
|
+
| Draft 0.3 name | 0.4 import |
|
|
168
|
+
|---|---|
|
|
169
|
+
| `@arnilo/prism-documents` | `@arnilo/prism-office/documents` |
|
|
170
|
+
| `@arnilo/prism-sheets` | `@arnilo/prism-office/sheets` |
|
|
171
|
+
| `@arnilo/prism-diagrams` | `@arnilo/prism-office/diagrams` |
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { generateDocument } from "@arnilo/prism-office/documents";
|
|
175
|
+
import { parseCsv } from "@arnilo/prism-office/sheets";
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`@office-open/{docx,xlsx,pptx,xml}` are exact-pinned regular dependencies of the
|
|
179
|
+
office tarball. The diagrams live-embed optionally peers `playwright-core`; XML
|
|
180
|
+
canonicalization does not.
|
|
181
|
+
|
|
182
|
+
### Removed profile packages
|
|
183
|
+
|
|
184
|
+
Profiles were dependency lists, not runtime APIs. Choose the families your host uses; do not look
|
|
185
|
+
for a 0.4 profile replacement package.
|
|
186
|
+
|
|
187
|
+
| Legacy 0.3 profile | 0.4 starting recipe |
|
|
188
|
+
|---|---|
|
|
189
|
+
| `@arnilo/prism-base` | `npm i @arnilo/prism@^0.4.0 @arnilo/prism-core@^0.4.0 @arnilo/prism-memory@^0.4.0` |
|
|
190
|
+
| `@arnilo/prism-code` | Base recipe + `@arnilo/prism-coding-tools@^0.4.0 @arnilo/prism-mcp@^0.4.0` |
|
|
191
|
+
| `@arnilo/prism-sdk` | Base recipe + `@arnilo/prism-mcp@^0.4.0`; Core contains credentials, observability, and workflows. |
|
|
192
|
+
| `@arnilo/prism-all` | Select required families explicitly. Begin with Core, Providers, Coding tools, Web tools, Memory, and required interop; add Office only if needed. |
|
|
193
|
+
|
|
194
|
+
### Names that remain
|
|
195
|
+
|
|
196
|
+
These package names remain valid. Review their imports if they now consume one of the new family
|
|
197
|
+
subpaths, but do not rename the dependency merely because of 0.4.
|
|
198
|
+
|
|
199
|
+
| Package | 0.4 status |
|
|
200
|
+
|---|---|
|
|
201
|
+
| `@arnilo/prism` | Unchanged root package; remains dependency-free. |
|
|
202
|
+
| `@arnilo/prism-providers` | Same name, now code family; provider imports use `/provider-name`. |
|
|
203
|
+
| `@arnilo/prism-web-tools` | Same name; root web tools unchanged, browser/Obscura use subpaths. |
|
|
204
|
+
| `@arnilo/prism-memory` | Same name; RAG/compaction/Graft/Wiki use subpaths. |
|
|
205
|
+
| `@arnilo/prism-mcp` | Unchanged interop package. |
|
|
206
|
+
| `@arnilo/prism-acp-agent` | Unchanged interop package. |
|
|
207
|
+
| `@arnilo/prism-ag-ui` | Unchanged interop package. |
|
|
208
|
+
|
|
209
|
+
## Optional peers, host binaries, and trust boundaries
|
|
210
|
+
|
|
211
|
+
Installing a family does not install or activate its optional capabilities. Add the peer only for
|
|
212
|
+
the subpath you use and preserve its existing host policy.
|
|
213
|
+
|
|
214
|
+
| Feature | Required host dependency / action | Do not weaken |
|
|
215
|
+
|---|---|---|
|
|
216
|
+
| SQLite sessions or prompt store | Install `better-sqlite3`; use only the selected `prism-core` session/governance subpath. | Database ownership, migration checks, and file permissions. |
|
|
217
|
+
| PostgreSQL sessions, prompts, or enterprise state | Install `pg`; use the selected `prism-core` subpath. | TLS, roles, checksummed migrations, and tenant boundaries. |
|
|
218
|
+
| NATS sessions | Install/configure the NATS client required by the sessions NATS subpath. | Stream/consumer ownership and durable cursor isolation. |
|
|
219
|
+
| Browser tools | Install `playwright-core` and provide the approved host browser/context. | Egress, upload/download, screenshot, and side-effect policies. |
|
|
220
|
+
| Obscura | Install/configure `playwright-core`, `@arnilo/prism-mcp`, and an approved host Obscura binary. | Absolute shell-free command, SSRF controls, process limits, MCP authorization. |
|
|
221
|
+
| Document reader | Install `mammoth` and/or `pdf-parse` for used formats. | Magic-byte format gating, input/page/text caps, and no embedded-content execution. |
|
|
222
|
+
| Graft | Install/configure `@nanonets/graft` or approved host CLI. | Workspace confinement, output/time limits, and no implicit process start. |
|
|
223
|
+
| Wiki | Provide the documented host `qmd`/Context7 setup when using Wiki commands. | Workspace path, process, and untrusted-content limits. |
|
|
224
|
+
| Computer Use Linux | Provide the approved `computer-use-linux` MCP host binary. | Consent, sandbox, approval, serialized input, and redaction. |
|
|
225
|
+
|
|
226
|
+
## Recommended upgrade sequence
|
|
227
|
+
|
|
228
|
+
1. **Move root/version first.** Set `@arnilo/prism` to `^0.4.0`; retain the Node version required
|
|
229
|
+
by the release.
|
|
230
|
+
2. **Replace retired dependency names.** Use the appropriate family package in `package.json`.
|
|
231
|
+
3. **Replace imports.** Apply the tables above. Do not keep both old and new imports in the same
|
|
232
|
+
runtime path.
|
|
233
|
+
4. **Add only needed peers.** Follow the previous table; subpath import failures should name the
|
|
234
|
+
missing peer rather than fall back to an unsafe implementation.
|
|
235
|
+
5. **Recheck host wiring.** Re-register tools/providers/extensions explicitly. Package install
|
|
236
|
+
remains inert; it must not activate providers, listeners, database connections, browsers,
|
|
237
|
+
credentials, or tools.
|
|
238
|
+
6. **Run verification.**
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
npm run typecheck
|
|
242
|
+
npm test
|
|
243
|
+
npm pack --dry-run
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Run protected PostgreSQL, browser, Obscura, MCP, or host-binary checks separately when your
|
|
247
|
+
application uses those integrations.
|
|
248
|
+
|
|
249
|
+
## Legacy warning and lifecycle
|
|
250
|
+
|
|
251
|
+
Each retired package's final 0.3 release is marked with npm's `legacy` dist-tag and a deprecation
|
|
252
|
+
warning like:
|
|
253
|
+
|
|
254
|
+
```text
|
|
255
|
+
npm warn deprecated @arnilo/prism-browser@0.3.x:
|
|
256
|
+
Legacy 0.3 package. Prism 0.4+: @arnilo/prism-web-tools/browser.
|
|
257
|
+
https://github.com/ashiqrniloy/prism/blob/main/docs/migrate-to-0.4.md#web-browser-and-obscura
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The warning is informational: it does not delete the package or rewrite your dependency. `latest`
|
|
261
|
+
continues to point at the final 0.3 release because npm dist-tags cannot redirect one package name
|
|
262
|
+
to a different package. New 0.4 development must use the successor listed above.
|
|
263
|
+
|
|
264
|
+
The markers are generated and applied from one reviewed registry plan — never hand-copied. Run
|
|
265
|
+
`node scripts/phase54-legacy-registry.mjs --dry-run` to resolve every retired name's final
|
|
266
|
+
published version, verify the anchors above exist in this guide, and print the exact
|
|
267
|
+
`npm dist-tag add ... legacy` and `npm deprecate ..."<0.4.0"` commands without mutating the
|
|
268
|
+
registry. After the 0.4 packages and this guide are public (Task 9 cutover),
|
|
269
|
+
`node scripts/phase54-legacy-registry.mjs --apply --confirm` pre-flights every entry and fails
|
|
270
|
+
closed — zero mutations — on any mismatch, then applies the tags and warnings idempotently:
|
|
271
|
+
already-correct entries are skipped on resume, and per-entry status is written to
|
|
272
|
+
`release-artifacts/legacy-registry-plan.json` for safe resume. Two retired names
|
|
273
|
+
(`@arnilo/prism-prompts`, `@arnilo/prism-dev`) were never published; they are recorded in the
|
|
274
|
+
plan with no registry action.
|
|
275
|
+
|
|
276
|
+
## Rollback
|
|
277
|
+
|
|
278
|
+
If the 0.4 migration fails before deployment:
|
|
279
|
+
|
|
280
|
+
1. Restore the committed 0.3.x `package.json` and lockfile.
|
|
281
|
+
2. Restore old imports from the mapping table.
|
|
282
|
+
3. Reinstall with the lockfile (`npm ci`).
|
|
283
|
+
4. Do not unpublish any package or remove the `legacy` marker; those are registry metadata, not a
|
|
284
|
+
runtime migration.
|
|
285
|
+
|
|
286
|
+
The package reorganization itself does not change persisted store schemas. If the same deployment
|
|
287
|
+
also adopted a separate database/session feature release, follow that feature's migration and
|
|
288
|
+
rollback instructions; do not assume package rollback reverses a forward-only database migration.
|
|
289
|
+
|
|
290
|
+
## FAQ
|
|
291
|
+
|
|
292
|
+
**Can I install `@arnilo/prism-all` in 0.4?** No. It was a pure manifest and is retired. Install
|
|
293
|
+
only the family packages your host needs.
|
|
294
|
+
|
|
295
|
+
**Why is `@arnilo/prism-core` separate from `@arnilo/prism`?** Root Prism remains dependency-free.
|
|
296
|
+
Database drivers, optional Node integrations, and governance/runtime modules must not become
|
|
297
|
+
implicit root dependencies.
|
|
298
|
+
|
|
299
|
+
**Why not keep old packages as wrappers?** Wrappers preserve 54 active manifests and create a
|
|
300
|
+
cycle if a new family imports the old implementation while the old package re-exports the family.
|
|
301
|
+
The direct migration is smaller and unambiguous.
|
|
302
|
+
|
|
303
|
+
**Do unchanged interop packages need changes?** No package-name change. Keep MCP, ACP, AG-UI, or
|
|
304
|
+
Antigravity installed only when your host uses that protocol; update imports only if their own 0.4
|
|
305
|
+
API page says so.
|
|
306
|
+
|
|
307
|
+
## Related APIs
|
|
308
|
+
|
|
309
|
+
- [Release and install](release-and-install.md): package contents, peer rules, and publication.
|
|
310
|
+
- [Migration guide](migration.md): migration history for prior releases.
|
|
311
|
+
- [Provider packages](provider-packages.md): provider adapter behavior.
|
|
312
|
+
- [Host security guide](host-security.md): preserve host trust boundaries while upgrading.
|