@daniel156161/prism
v0.3.23
Published
Prism-branded wrapper around pi that stores config in ~/.prism
Maintainers
Readme
Prism
Prism is a branded harness around the pi coding agent.
It bundles the pi runtime, keeps all agent state in ~/.prism, patches pi in-place for Prism branding
and behavior, and ships a set of built-in extensions: planning, research, memory integrations
(Obsidian, Logseq), a code-graph integration (mex), a hidden diagnostic toolbox, role-play long-term
context, local Ollama models and Manifest routing.
Prism does not embed pi as a library. It resolves the bundled pi CLI, sets Prism-specific env vars,
and idempotently patches the runtime package in ~/.prism/pi-package.
- Package:
@daniel156161/prism - Binary:
prism - Bundled pi runtime:
@earendil-works/pi-coding-agent0.87.1 - Node:
>=25 - Config/state:
~/.prism
Requirements
- Node.js
>=25 - No separate pi install needed —
@earendil-works/pi-coding-agentis abundledDependency. Override withPRISM_PI_CLI_PATHonly if you know the patch layer matches that pi version.
Optional, only needed for the features that use them:
mex-agent(npm install -g mex-agent) plus a.mex/scaffold for the code graph- a local or cloud Ollama instance for the
ollamaprovider
Install
npm install -g --legacy-peer-deps @daniel156161/prism--legacy-peer-deps is required: pi-mcp-adapter declares an optional peer on
@earendil-works/pi-ai@^0.84.1 || ^0.85.0 while Prism ships pi 0.87.x. Without the flag npm "overrides" that
peer and silently drops the whole MCP subtree (pkce-challenge, jose, zod, ajv,
eventsource), which only surfaces later as a missing-module crash at runtime.
The binary is:
prism
prism --versionRun from source
npm install
npm run devA justfile wraps the common workflows (just --list), including the Docker sandbox in sandbox-kit/.
CLI
Subcommands
prism auth status
prism auth list
prism auth save work|private
prism auth use work|private
prism auth work
prism auth private
prism obsidian-memory append [--path NOTE] [--heading TITLE] <text>
prism obsidian-memory read [path]
prism obsidian-memory search [--limit N] [--subdir DIR] <query>
prism obsidian-memory list [--dir DIR] [--limit N]
# alias: prism memory ...Prism-specific flags
Consumed before the remaining args are handed to pi:
--caveman[=mode]— start in caveman mode. Bare--cavemanmeansfull. Modes:lite,full,ultra,wenyan-lite,wenyan,wenyan-ultra.--model provider:model— Prism normalizesprovider:model(colon) toprovider/model(slash) for pi compatibility.--model provider/modelworks directly. Known providers are read from the bundled pi model resolver.--auth-profile work|private— use a profile for a single run without moving theauth.profilemarker.
All other pi flags (--provider, --models, --no-tools, --list-models, --no-extensions, …)
pass through unchanged.
Config paths
Prism forces pi to use the Prism agent directory:
- default:
~/.prism - override:
PRISM_CODING_AGENT_DIR=/path/to/prism-dir
Important files:
~/.prism/settings.json~/.prism/models.json~/.prism/auth.json~/.prism/auth.private.json~/.prism/auth.work.json~/.prism/auth.profile— active auth profile marker~/.prism/sessions/— JSONL sessions~/.prism/sessions.db— SQLite mirror~/.prism/rp-state.json— active role-play marker~/.prism/pi-package/— lightweight piConfig dir (package.json, themes, linked pidocs/,examples/,README.md)
Project-local Prism resources live under the project .prism/ directory:
.prism/skills/<skill-name>/SKILL.md
.prism/settings.json
.prism/extensions/
.prism/prompts/
.prism/themes/Example skill path:
.prism/skills/last30days/SKILL.mdAfter trusting the project, Prism lists discovered project skills in a separate startup section:
[Skills]
last30days/skill:last30days is available as a slash command when skill commands are enabled.
WristPrompt server integration
Prism has a built-in WristPrompt extension that talks to your configured server API directly. It does not use local inbox files or a local bridge.
Configure it with a root API URL and a refresh token with the pebble scope.
Environment variables:
export PRISM_WRISTPROMPT_API_BASE_URL="https://example.com"
export PRISM_WRISTPROMPT_REFRESH_TOKEN="..."Or ~/.prism/settings.json:
{
"wristPrompt": {
"apiBaseUrl": "https://example.com",
"refreshToken": "..."
}
}Optional timeout:
export PRISM_WRISTPROMPT_TIMEOUT_MS=30000The extension is enabled automatically when both apiBaseUrl and refreshToken are configured.
When configured, Prism/pi gets the /wristprompt command. The request tools stay inactive until
watch input is enabled for the current session with /wristprompt:
wristprompt_ask blocking: create request + wait for the watch answer
wristprompt_check_request check one earlier request that timed out
wristprompt_cancel_request withdraw a request the agent created/wristprompt off disables watch input again and removes those request tools from the active tool set.
wristprompt_ask blocks on purpose. An agent turn ends as soon as the model stops, so a
fire-and-forget request could never be picked up again in the same turn. The tool creates the
request (POST /api/pebble/wristprompt), polls it (GET /api/pebble/wristprompt/<id>), and
returns as soon as the watch answers:
{ "request_id": "wrp_...", "status": "approved", "answered": true, "action": "approve", "message": "go", "waited_ms": 8123 }The wait window is not a tool parameter. The model always gets the full window, otherwise it could time itself out of an answer. Only you can change it, via env:
export PRISM_WRISTPROMPT_ASK_TIMEOUT_MS=600000 # default: 600 s
export PRISM_WRISTPROMPT_ASK_POLL_MS=2000 # poll interval while waiting
export PRISM_WRISTPROMPT_POLL_MS=3000 # claim interval for watch transcriptsOr in ~/.prism/settings.json, in milliseconds or seconds:
{
"wristPrompt": {
"apiBaseUrl": "https://example.com",
"refreshToken": "...",
"askTimeoutSeconds": 600,
"askPollSeconds": 2,
"pollSeconds": 3
}
}askTimeoutMs, askPollMs, and pollMs work too. Env wins over settings.json, and values below
the minimum (1 s timeout, 250 ms ask poll, 500 ms claim poll) fall back to the defaults.
On timeout or tool-call abort, Prism dismisses the watch request automatically so stale prompts do
not stay open. If that dismissal fails, the result keeps status: "pending" plus the request_id,
so the agent can check or cancel it later. The agent can only dismiss its own request;
approving/rejecting is the watch's job.
Watch input per session (opt-in)
Watch transcripts and WristPrompt request tools are never enabled automatically. Run /wristprompt inside the one session that should receive watch input and access to the WristPrompt tools:
/wristprompt # enable this session as watch-input listener
/wristprompt off # disable again
/wristprompt status # show current stateEnabling registers the current session (POST /api/pebble/wristprompt/sessions), so the watch can show and target it, and starts a claim loop (POST /api/pebble/wristprompt/input/claim). Each transcript is claimed exactly once, so it never fans out to other open sessions. The status-bar segment ⌚ <host> is only shown while a session is active, and the session is unregistered on shutdown. Claim failures are reported once and retried with exponential backoff up to 60 s; successful claims reset the backoff. Session registration also sends stale_after_ms (24 h), so the server can prune sessions that survived a hard process kill.
The extension refreshes 1-hour access tokens through POST /token/refresh and retries once after 401/403.
Sessions
Sessions are persisted immediately and mirrored into ~/.prism/sessions.db
(src/pi/pi-patch-session.ts, src/session-db.ts). Existing JSONL sessions are imported on startup.
PRISM_SESSION_BACKEND=db(default) — SQLite is authoritative, JSONL is imported and cleaned upPRISM_SESSION_BACKEND=file— plain pi JSONL behavior, no DB mirroring
Auth profiles
Keep separate private/work auth files and switch before pi starts:
prism auth save private
prism auth save work
prism auth private
prism auth work
prism auth statusSingle-run override without changing the marker:
prism --auth-profile work
prism --auth-profile=private "your prompt"Profiles live in ~/.prism:
auth.json— legacy auth file, unused by Prism profile switchingauth.private.json— private profileauth.work.json— work profileauth.profile— active profile marker (workorprivate)
Built-in commands
Always available:
/plan [task]— read-only planning mode; approve to restore full tool access. See plan mode./research <topic> [provider/model|pick]— citation-backed web research workflow./context— visual context usage grid (system prompt, tools, skills, project context, messages)./toolbox <query>— search hidden toolbox tools./git-commit— ask the current model to create a signed git commit from staged changes./clearor/cls— clear terminal/scrollback and start a fresh session./caveman [lite|full|ultra|wenyan-lite|wenyan|wenyan-ultra|off]— concise response modes./exit— optional session-end workflow (daily note / insight / inbox cleanup) before shutdown.
Memory:
/obsidian-note— ask the current model to write or update Obsidian notes from the current context./obsidian-commit— commit staged Obsidian vault changes with an automatic German commit message./logseq— show Logseq vault status and the default journal path./rp [status] | list | new <name> | start <name> | stop | recap— manage role-plays.
Safe harness improvement (all human-gated, see docs/safe-harness-improvement.md):
/self-improve [focus]— read-only inspection, then concrete proposals with blast radius, validation plan and rollback./eval [focus]— read-only regression/eval pass, compared against prior eval logs./vote <task>— multi-perspective review without implementing anything./prompt-review <focus>— review prompts/behavior patterns and propose safer candidates.
Conditional:
/ollama status|refresh|list|running|version|show <model>|pull <model>and/ollama-refresh— when Ollama is reachable./manifest status|tier <tier>— when a Manifest base URL is configured./mex [status] | graph | check | timeline | scope <task>— when the mex CLI and a.mex/scaffold exist.
From bundled npm extensions:
/voice— local speech dictation overlay (@juicesharp/rpiv-voice)./todos— agent todo list (@juicesharp/rpiv-todo), panel togglectrl+shift+t.
Built-in tools
Obsidian memory:
obsidian_memory_append obsidian_memory_read obsidian_memory_search obsidian_memory_listLogseq memory:
logseq_append logseq_read logseq_search logseq_listResearch:
web_search web_fetchweb_search and web_fetch prefer a local-first NodeSeek backend when its health
endpoint answers. web_search falls back to DuckDuckGo and Bing, web_fetch falls back
to a direct page fetch. YouTube transcripts (yt-dlp) and GitHub handling always run first.
NodeSeek graph tools (loaded only when the service answers at startup):
nodeseek_context nodeseek_navigatePRISM_NODESEEK_URL default http://127.0.0.1:8000, use "off" to disable
PRISM_NODESEEK_AVAILABILITY_TIMEOUT_SECONDS default 0.5 curl budget per startup probe
PRISM_NODESEEK_STARTUP_ATTEMPTS default 2 startup probes before giving up
PRISM_NODESEEK_HEALTH_TIMEOUT_MS default 1200 runtime health check
PRISM_NODESEEK_HEALTH_CACHE_TTL_MS default 30000 health result cache
PRISM_NODESEEK_SEARCH_TIMEOUT_MS default 12000 /v1/search
PRISM_NODESEEK_READ_TIMEOUT_MS default 15000 /v1/read
PRISM_NODESEEK_GRAPH_TIMEOUT_MS default 12000 /v1/context + /v1/navigateEvery value can also come from the nodeseek block in settings.json (env wins over
settings, settings win over the defaults):
{
"nodeseek": {
"baseUrl": "https://nodeseek.example",
"availabilityTimeoutSeconds": 1,
"startupAttempts": 3,
"healthTimeoutMs": 3000,
"healthCacheTtlMs": 60000,
"searchTimeoutMs": 20000,
"readTimeoutMs": 25000,
"graphTimeoutMs": 20000
}
}For a remote NodeSeek host, raise the timeouts and keep startupAttempts above 1: a
single failed startup probe is usually a stalled DNS lookup on the client, and a retry
resolves it without disabling the graph tools for the whole session.
Role-play context:
rp_state rp_update rp_searchSafe harness improvement:
self_improvement_record self_improvement_list self_improvement_update_proposalmex code graph (conditional):
mex_scope mex_get mex_query mex_impact mex_logHidden toolbox:
toolbox_search toolbox_executeHidden toolbox
Hidden tools are not listed in the system prompt. The agent discovers them with toolbox_search
and runs them with toolbox_execute; relevant candidates are also suggested per turn.
Extensions can register their own via the toolbox:register event.
Built-in toolbox tools (src/prism-extensions/tools/) are read-only diagnostics unless noted:
| Tool | Purpose |
|---|---|
| ssh_config | Read ~/.ssh/config, show host context, optional read-only SSH status checks |
| docker_status | Containers, compose services, images, disk usage |
| docker_logs | Recent logs from a local container |
| systemd_services | Running/failed units or status for one unit |
| port_check | TCP reachability from this machine |
| http_health | HTTP status, content type, selected headers, small body preview |
| process_find | Find local processes by text query |
| ssh_remote_logs | Docker/systemd logs on a configured SSH host |
| netbird_status | Local or remote NetBird status, peers, service state |
| pfsense_status | pfSense/OPNsense health: uptime, interfaces, states, gateways, DNS, disk |
| borg_backup_info | borg info/borg list on a backup repository |
| prism_runtime_status | Prism runtime/config paths, versions, sessions DB, auth marker |
| prism_deploy_check | Read-only checks for a deployed Prism SSH/tmux container |
| npm_package_version | Latest published version from an npm-compatible registry metadata endpoint |
| portainer_webhook | Inspect or trigger a Portainer stack webhook (dry-run by default) |
| mex_graph_build | Rebuild .mex/graph.db |
| mex_check | mex drift detection between the .mex wiki and the codebase |
| mex_timeline | mex event-log timeline |
Plan mode tool filter
/plan narrows the session to the intersection of the active tools and the allowlist in
src/pi/plan-mode-tools.ts (PRISM_PLAN_MODE_READ_ONLY_TOOLS), and restores the previous tool set
when the plan is approved, rejected or cancelled.
Allowed: pi built-ins read/grep/find/ls, web_search/web_fetch,
obsidian_memory_read|search|list, logseq_read|search|list, mex_scope|get|query|impact,
rp_state/rp_search, toolbox_search, self_improvement_list, todo.
Deliberately excluded: bash, edit, write, every *_append and vault-write tool,
mex_log, rp_update, toolbox_execute, self_improvement_record|update_proposal, mcp, mcpScript.
Only add non-mutating tools. prismPlanReadOnlyToolSetDeclaration() builds the set for the runtime
patch; refreshPrismPlanReadOnlyToolSet() updates an already-patched runtime.
Obsidian memory
Vault selection is env-only. Prism intentionally ignores ~/.prism/settings.json and generic
OBSIDIAN_VAULT / OBSIDIAN_VAULT_NAME so it never falls back to a personal/default vault by accident.
export PRISM_OBSIDIAN_VAULT_NAME=AI-Worker # resolved via: obsidian vault info=path vault=AI-Worker
export PRISM_OBSIDIAN_VAULT=/path/to/vault # or pin an explicit pathFallbacks: PI_OBSIDIAN_VAULT_NAME, PI_OBSIDIAN_VAULT. An explicitly empty
PRISM_OBSIDIAN_VAULT_NAME/PRISM_OBSIDIAN_VAULT stays empty and does not fall back.
CLI behavior:
- Memory tools use the Obsidian CLI when
PRISM_OBSIDIAN_VAULT_NAMEis set (read,append,property:set,files,search:context). Missing notes are created withcreate; full overwrite is only used when existing note structure must be normalized. - The vault is passed as a leading global option (
obsidian vault=AI-Worker ...) because the CLI ignores trailingvault=...for some commands. - Auto-context uses the resolved vault path for direct Markdown scanning/injection.
- Obsidian CLI calls time out to avoid hangs when Obsidian is not running.
Default:
PRISM_OBSIDIAN_CLI_TIMEOUT_MS=5000.
Auto-context behavior:
00 Kontext/is injected as full always-loaded background context.- Prompt-relevant memories are injected only as compact candidates: path, description, score, tags.
- The model calls
obsidian_memory_readfor a candidate path only when full note context is needed. PI_OBSIDIAN_CONTEXT_DIRrestricts candidate search to one vault subdirectory.
Vault structure used by Prism:
MEMORY.mdroot index, no YAML frontmatter00 Kontext/always-loaded background context01 Inbox/unsorted captures02 Projekte/projects03 Bereiche/areas04 Ressourcen/references/resources05 Daily Notes/daily notes06 Archiv/archived notesRP/<slug>/role-play long-term contextPi/pi/prism-specific notes
Logseq memory
export PRISM_LOGSEQ_VAULT=/path/to/logseq-graph
export PRISM_LOGSEQ_CONTEXT_DIR=pages # optional: restrict candidate search
export PRISM_LOGSEQ_ALWAYS_CONTEXT=Kontext # optional: always-loaded namespace prefixFallbacks: PI_LOGSEQ_VAULT, PI_LOGSEQ_CONTEXT_DIR, PI_LOGSEQ_ALWAYS_CONTEXT.
Pages under the Kontext/... namespace are injected as always-loaded context; other matches are
injected as compact per-turn candidates. Writes go to pages/<Name>.md, journal-style names
(YYYY_MM_DD) to journals/. Without a path, logseq_append targets today's journal.
Role-play context
/rp stores long-term role-play context in the Obsidian vault so it survives session resets:
<vault>/RP/<slug>/Overview.md premise, setting, tone, rules
<vault>/RP/<slug>/Characters.md "## <Name>" persona sections
<vault>/RP/<slug>/World.md "## <Topic>" lore sections
<vault>/RP/<slug>/State.md running recap, current scene, relationships, threads
<vault>/RP/<slug>/Story.md chronological prose archive (searchable, not always-loaded)Multiple role-plays live side by side. The active one is tracked in ~/.prism/rp-state.json, outside
the vault, so rp_state/rp_update/rp_search can be gated. Overview/Characters/World/State
are always-loaded while a role-play runs; the toolbar shows a segment only then.
mex code graph
integrations/mex-memory.ts loads only when the mex CLI (npm install -g mex-agent) is installed
and the repo has a .mex/ scaffold (npx mex-agent setup). It exposes mex_scope, mex_get,
mex_query, mex_impact, mex_log and /mex; maintenance lives in the hidden toolbox
(mex_graph_build, mex_check, mex_timeline).
When active, .mex/AGENTS.md (frontmatter stripped, max 8000 chars) is injected as an always-loaded
context file, so the agent knows the graph and scaffold exist without being told.
A missing .mex/graph.db is rebuilt automatically (core/mex-graph-db.ts): in the background on
session start, and lazily before the first graph-reading tool call. Builds are deduplicated per
scaffold and never fail hard. Without a scaffold nothing is ever built.
The 🕸 mex toolbar segment appears only when mex really works (scaffold and non-empty graph.db);
🕸 mex ⟳ while a build runs; nothing when disabled, scaffold-less or failed.
Env switches:
PRISM_DISABLE_MEX=1— off entirelyPRISM_MEX_FORCE=1— load without a scaffoldPRISM_MEX_BIN— custom binary pathPRISM_MEX_TELEMETRY=1— allow mex telemetry (Prism otherwise setsDO_NOT_TRACK=1/MEX_TELEMETRY=0)PRISM_DISABLE_MEX_ANCHOR=1— do not inject.mex/AGENTS.mdPRISM_DISABLE_MEX_AUTO_GRAPH=1— never auto-buildgraph.db
Provider extensions
Provider integrations live under src/prism-extensions/providers/ and are loaded conditionally.
Ollama provider
Loaded when ${OLLAMA_BASE_URL}/api/tags responds with at least one model and
PRISM_DISABLE_OLLAMA is not 1. Prism registers a dynamic ollama provider from Ollama's live API
(/api/tags, /api/show, /api/ps, /api/version) and serves models through the OpenAI-compatible
/v1 API: streaming, tools, vision when capabilities report it, structured outputs/JSON mode,
usage metrics, and reasoning controls for thinking models.
/ollama status | refresh | list | running | version | show <model> | pull <model>
/ollama-refreshManifest provider
Loaded when a Manifest base URL is configured via env or ~/.prism/settings.json. The API key goes
through pi's normal auth flow (/login → API key → Manifest) into the active Prism auth profile.
~/.prism/settings.json:
{
"manifestProvider": {
"baseUrl": "https://manifest.example/v1",
"tier": "plan"
}
}prism
# /login → Use an API key → Manifest
# /model manifest/autoEnv overrides take precedence over settings:
export PRISM_MANIFEST_BASE_URL="https://manifest.example/v1"
export PRISM_MANIFEST_API_KEY="mnfst_..." # optional alternative to /login
export PRISM_MANIFEST_MODEL="auto" # optional
export PRISM_MANIFEST_TIER="plan" # auto (no tier header) or a custom tier
export PRISM_MANIFEST_ENABLE_IMAGES="1" # opt-in, see below
prism --model manifest/autoAt runtime:
/manifest status
/manifest tier plan | research | autoPrism forwards Manifest custom routing headers and shows response metadata (X-Manifest-Tier,
X-Manifest-Model, fallback headers, …) in the status line. Manifest is registered as
reasoning-capable, so thinking levels are forwarded as OpenAI-compatible reasoning_effort.
Image input is opt-in (PRISM_MANIFEST_ENABLE_IMAGES=1 or manifestProvider.enableImages: true).
By default Manifest is registered text-only because its public docs document OpenAI-compatible chat
routing but do not guarantee vision routing for every resolved upstream model.
Bundled npm extensions
Beyond the source extensions, Prism loads npm packages that ship a pi manifest
(PRISM_BUILTIN_NPM_EXTENSION_PACKAGES in src/pi/pi-extensions.ts):
pi-mcp-adapter— MCP tools (mcp,mcpScript)@juicesharp/rpiv-voice—/voicedictation via local Whisper (sherpa-onnx); the model is downloaded on first use into~/.pi/models/whisper-base/@juicesharp/rpiv-todo—todotool,/todos, and a panel above the editor; state is session-scoped and rebuilt from the conversation
Entry resolution (src/pi/pi-npm-extension-entry.ts) supports both packages with exports/main
and packages that only declare their entry in pi.extensions. The latter count as Prism-internal,
so e.g. /voice shows up without a package prefix.
Runtime patching
Prism accepts only the pi runtime version it was built against:
SUPPORTED_PI_CODING_AGENT_VERSION = "0.87.1"Patches run against compiled pi JavaScript with exact string replacements via replaceRequired(),
which is idempotent. Never hand-edit pi in node_modules — change src/pi/pi-patch-*.ts instead.
Patch areas:
pi-patch-auth.ts— auth storage usesPRISM_AUTH_PATH/PI_AUTH_PATHpi-patch-interactive.ts— Prism/▲ branding, process title, plan-mode tool filter, usage-limit recovery menu instead of generic autoretry,_isRetryableErrorhardened forusage_limit_reachedpi-patch-session.ts— immediate persistence plus the~/.prism/sessions.dbmirrorpi-patch-system-prompt.ts— documentation block focused on project documentationpi-patch-context-files.ts— extra always-loaded context files (PRISM_EXTRA_CONTEXT_FILES)pi-patch-extension-loader.ts— treat Prism's own extensions as internal (no package prefix)pi-patch-autocomplete.ts— command/argument completion behaviorpi-package.ts— build~/.prism/pi-packageand link the bundled pidocs/,examples/,README.md
When updating pi:
npm outdated
npm run package:update-check
npm test
npm run typecheck
npm run build
node --import tsx/esm src/cli.ts --versionEnvironment variables
Core:
PRISM_CODING_AGENT_DIR— Prism config/state directory, default~/.prismPRISM_PI_CLI_PATH/PI_CLI_PATH— override the bundled pi CLIPRISM_SESSION_BACKEND—db(default) orfilePRISM_AUTH_PROFILE— active auth profile for this processPRISM_CAVEMAN_MODE/CAVEMAN_MODE— default caveman mode
Obsidian:
PRISM_OBSIDIAN_VAULT_NAME— Obsidian CLI vault name (env-only resolution)PRISM_OBSIDIAN_VAULT— explicit vault pathPI_OBSIDIAN_VAULT_NAME/PI_OBSIDIAN_VAULT— fallbacksPI_OBSIDIAN_CONTEXT_DIR— restrict prompt-relevant memory search to a subdirectoryPRISM_OBSIDIAN_INJECT_CANDIDATES— number of per-turn candidatesPRISM_OBSIDIAN_CLI_TIMEOUT_MS— Obsidian CLI timeout, default5000
Logseq:
PRISM_LOGSEQ_VAULT/PI_LOGSEQ_VAULT— Logseq graph pathPRISM_LOGSEQ_CONTEXT_DIR/PI_LOGSEQ_CONTEXT_DIR— restrict candidate searchPRISM_LOGSEQ_ALWAYS_CONTEXT/PI_LOGSEQ_ALWAYS_CONTEXT— always-loaded namespace prefix, defaultKontext
Ollama:
PRISM_DISABLE_OLLAMA=1— disable the providerPRISM_OLLAMA_BASE_URL/OLLAMA_BASE_URL— accepts/api,/v1or root; defaulthttp://localhost:11434/v1PRISM_OLLAMA_API_KEY/OLLAMA_API_KEY— Ollama Cloud key; local Ollama ignores keysPRISM_OLLAMA_CONTEXT_WINDOW/OLLAMA_CONTEXT_WINDOW— fallback context window, default128000PRISM_OLLAMA_MAX_TOKENS/OLLAMA_MAX_TOKENS— max output tokens, default32000PRISM_OLLAMA_SHOW_DETAILS=0— skip/api/showcapability lookupsPRISM_OLLAMA_TIMEOUT_MS— API timeoutPRISM_OLLAMA_AVAILABILITY_TIMEOUT_SECONDS— startup probe timeout, default0.5
Manifest (each has a MANIFEST_* fallback):
PRISM_MANIFEST_BASE_URL,PRISM_MANIFEST_API_KEY,PRISM_MANIFEST_MODEL(defaultauto)PRISM_MANIFEST_TIER— custom tier header;autosends nonePRISM_MANIFEST_ENABLE_IMAGES=1— opt into image inputPRISM_MANIFEST_CONTEXT_WINDOW,PRISM_MANIFEST_MAX_TOKENS
mex: see mex code graph.
SSH/tmux container
A CI-built container with key-only SSH, tmux and the Prism package from the latest pushed commit:
docker compose -f compose.ssh-prism.yml pull
docker compose -f compose.ssh-prism.yml up -d
docker compose -f compose.ssh-prism.yml exec prism-ssh prism-tmuxprism-tmux reconnects to an existing tmux session named prism; otherwise it creates one and
starts prism. See docs/ssh-tmux-container.md.
For a local throwaway sandbox with Manifest routing, see
sandbox-kit/README.md and the just sandbox-* recipes.
Repository layout
src/
├── cli.ts # entry point + CLI subcommands
├── session-db.ts # import/mirror existing JSONL sessions
├── pi/
│ ├── pi-native.ts # delegation to the bundled pi CLI
│ ├── pi-env.ts # runtime paths, version guard, patch helpers
│ ├── pi-package.ts # build ~/.prism/pi-package + patch the runtime
│ ├── pi-extensions.ts # auto-loaded built-in extensions
│ ├── pi-patch-*.ts # runtime patches (auth, interactive, session, prompt, …)
│ ├── plan-mode-tools.ts # read-only tool allowlist for /plan
│ └── prism-auth.ts # private/work auth profiles
└── prism-extensions/
├── commands/ # slash commands
├── core/ # shared config, vault, fuzzy, stores
├── integrations/ # Obsidian, Logseq, mex, research, role-play
├── providers/ # Ollama, Manifest
├── tools/ # hidden toolbox + toolbox tools
└── ui/ # toolbar, context usage, status, tool renderingTests live in tests/ and tests/prism-extensions/.
src/pi/pi-extensions.ts is the single manifest for which extension entrypoints load automatically —
a new built-in extension must be listed there.
Development
npm run typecheck
npm test
npm run buildPackage helpers:
npm run package:build
npm run package:update-check
npm run package:update-build
npm run package:publish:npm # @daniel156161/prism to npmjsFurther docs:
docs/safe-harness-improvement.md— self-improvement workflow and safety boundariesdocs/ssh-tmux-container.md— SSH/tmux containerdocs/pi/— vendored pi documentation.mex/ROUTER.md— code-graph scaffold navigation
License
MIT — see LICENSE.
