prism-mcp-server 20.2.1 → 20.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +220 -45
- package/dist/browserCli.js +56 -0
- package/dist/cli.js +240 -33
- package/dist/config.js +12 -6
- package/dist/connect.js +848 -15
- package/dist/dashboard/server.js +9 -14
- package/dist/dashboard/settingsPolicy.js +41 -0
- package/dist/localFirstPolicy.js +20 -0
- package/dist/onboarding/wizard.js +3 -6
- package/dist/server.js +77 -65
- package/dist/session/sessionContext.js +5 -3
- package/dist/skillManifestSync.js +943 -0
- package/dist/storage/configStorage.js +110 -1
- package/dist/storage/index.js +4 -3
- package/dist/storage/inferMetricsLedger.js +72 -14
- package/dist/storage/panelMetricsSpool.js +324 -0
- package/dist/storage/synalux.js +18 -1
- package/dist/tools/__tests__/ledgerHandlers.test.js +13 -0
- package/dist/tools/index.js +2 -2
- package/dist/tools/ledgerHandlers.js +468 -53
- package/dist/tools/prismInferHandler.js +171 -12
- package/dist/tools/sessionMemoryDefinitions.js +51 -10
- package/dist/tools/skillRouting.js +39 -7
- package/dist/tools/taskRouterHandler.js +184 -29
- package/dist/utils/inferenceMetrics.js +22 -3
- package/dist/utils/modelPicker.js +3 -3
- package/dist/utils/synaluxJwt.js +2 -1
- package/docs/prism-browser.md +89 -0
- package/package.json +6 -2
- package/scripts/dev/browse.py +1345 -0
package/dist/cli.js
CHANGED
|
@@ -7,13 +7,87 @@ import { getStorage, closeStorage } from './storage/index.js';
|
|
|
7
7
|
import { getSetting } from './storage/configStorage.js';
|
|
8
8
|
import { PRISM_USER_ID, SERVER_CONFIG } from './config.js';
|
|
9
9
|
import { getCurrentGitState } from './utils/git.js';
|
|
10
|
-
import { sessionLoadContextHandler, sessionSaveLedgerHandler, sessionSaveHandoffHandler } from './tools/ledgerHandlers.js';
|
|
11
|
-
import { connectHosts, normalizeHostName } from './connect.js';
|
|
10
|
+
import { sessionBootstrapHandler, sessionLoadContextHandler, sessionSaveLedgerHandler, sessionSaveHandoffHandler, } from './tools/ledgerHandlers.js';
|
|
11
|
+
import { configureClaudeAgentPolicy, configureClaudeNativeStartup, configureCodexAgentPolicy, configureCodexNativeStartup, configureGeminiAgentPolicy, configureGeminiNativeStartup, connectHosts, migrateLegacyClaudeHooks, migrateLegacyClaudeInstructions, migrateLegacyClaudeManagedStartup, migrateLegacyClaudeProjectMcp, normalizeHostName, } from './connect.js';
|
|
12
|
+
import { runBrowserCli } from './browserCli.js';
|
|
12
13
|
const program = new Command();
|
|
14
|
+
/** Build the stable `prism load --json` envelope from depth-specific context. */
|
|
15
|
+
export function buildLoadJsonOutput(project, data, level, metadata) {
|
|
16
|
+
let history = [];
|
|
17
|
+
let historyLimit = 0;
|
|
18
|
+
if (level === 'standard') {
|
|
19
|
+
history = Array.isArray(data.recent_sessions) ? data.recent_sessions : [];
|
|
20
|
+
historyLimit = 5;
|
|
21
|
+
}
|
|
22
|
+
else if (level === 'deep') {
|
|
23
|
+
// Canonical deep context uses session_history. Fall back only when that
|
|
24
|
+
// field is absent so older portal responses remain consumable.
|
|
25
|
+
history = Array.isArray(data.session_history)
|
|
26
|
+
? data.session_history
|
|
27
|
+
: Array.isArray(data.recent_sessions)
|
|
28
|
+
? data.recent_sessions
|
|
29
|
+
: [];
|
|
30
|
+
historyLimit = 50;
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
agent_name: metadata.agentName || null,
|
|
34
|
+
handoff: [{
|
|
35
|
+
project,
|
|
36
|
+
role: metadata.effectiveRole || data.role || 'global',
|
|
37
|
+
last_summary: data.last_summary || null,
|
|
38
|
+
pending_todo: data.pending_todo || null,
|
|
39
|
+
active_decisions: data.active_decisions || null,
|
|
40
|
+
keywords: data.keywords || null,
|
|
41
|
+
key_context: data.key_context || null,
|
|
42
|
+
active_branch: data.active_branch || null,
|
|
43
|
+
version: data.version ?? null,
|
|
44
|
+
updated_at: data.updated_at || null,
|
|
45
|
+
}],
|
|
46
|
+
// Keep the established key for callers while sourcing the canonical field
|
|
47
|
+
// for the requested depth.
|
|
48
|
+
recent_ledger: history.slice(0, historyLimit).map((entry) => ({
|
|
49
|
+
summary: entry?.summary || null,
|
|
50
|
+
decisions: entry?.decisions || null,
|
|
51
|
+
keywords: entry?.keywords || null,
|
|
52
|
+
created_at: entry?.session_date || entry?.created_at || null,
|
|
53
|
+
})),
|
|
54
|
+
git_hash: metadata.gitHash,
|
|
55
|
+
git_branch: metadata.gitBranch,
|
|
56
|
+
pkg_version: metadata.packageVersion,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
13
59
|
program
|
|
14
60
|
.name('prism')
|
|
15
61
|
.description('Prism — The Mind Palace for AI Agents')
|
|
16
62
|
.version(SERVER_CONFIG.version);
|
|
63
|
+
/** Print the canonical hook-free first-turn display used by the MCP tool. */
|
|
64
|
+
export async function runBootstrapCommand() {
|
|
65
|
+
try {
|
|
66
|
+
const result = await sessionBootstrapHandler({});
|
|
67
|
+
const output = result.content?.map((part) => part?.text).filter(Boolean).join('\n') || '';
|
|
68
|
+
if (!output)
|
|
69
|
+
throw new Error('session_bootstrap returned no display content');
|
|
70
|
+
console.log(output);
|
|
71
|
+
if (result.isError)
|
|
72
|
+
process.exitCode = 1;
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
console.error(`Bootstrap failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
76
|
+
process.exitCode = 1;
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
await closeStorage().catch(() => { });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
program
|
|
83
|
+
.command('bootstrap')
|
|
84
|
+
.description('Print the canonical dashboard-configured first-turn Prism greeting')
|
|
85
|
+
.action(runBootstrapCommand);
|
|
86
|
+
// Parsed by the direct dispatch at the bottom so all Python CLI flags pass
|
|
87
|
+
// through unchanged. Registering it here keeps the command visible in help.
|
|
88
|
+
program
|
|
89
|
+
.command('browser')
|
|
90
|
+
.description('Run the packaged local Prism Browser automation CLI');
|
|
17
91
|
// ─── prism connect ────────────────────────────────────────────
|
|
18
92
|
// Registers this installed package with supported MCP hosts. The
|
|
19
93
|
// merge is additive: an existing `prism` or `prism-mcp` entry is
|
|
@@ -25,7 +99,7 @@ program
|
|
|
25
99
|
.option('--all', 'Target all supported hosts instead of auto-detecting installed hosts')
|
|
26
100
|
.option('--dry-run', 'Preview configuration changes without writing files')
|
|
27
101
|
.option('--refresh', 'Refresh only entries previously created by Prism; custom entries stay untouched')
|
|
28
|
-
.action((options) => {
|
|
102
|
+
.action(async (options) => {
|
|
29
103
|
try {
|
|
30
104
|
if (!options.dryRun) {
|
|
31
105
|
console.log('Close target MCP hosts before registration so they cannot edit configuration concurrently.');
|
|
@@ -63,9 +137,144 @@ program
|
|
|
63
137
|
process.exitCode = 1;
|
|
64
138
|
}
|
|
65
139
|
}
|
|
140
|
+
const connectedClaude = summary.results.some((result) => result.host === 'claude-code' && result.status !== 'error' && result.startupCompatible);
|
|
141
|
+
const connectedGemini = summary.results.some((result) => result.host === 'gemini' && result.status !== 'error' && result.startupCompatible);
|
|
142
|
+
const connectedCodex = summary.results.some((result) => result.host === 'codex' && result.status !== 'error' && result.startupCompatible);
|
|
66
143
|
if (options.dryRun) {
|
|
144
|
+
if (connectedClaude) {
|
|
145
|
+
const projectMcpMigration = migrateLegacyClaudeProjectMcp(undefined, undefined, true);
|
|
146
|
+
const hookMigration = migrateLegacyClaudeHooks(undefined, true);
|
|
147
|
+
const instructionMigration = migrateLegacyClaudeInstructions(undefined, true);
|
|
148
|
+
const managedMigration = migrateLegacyClaudeManagedStartup(undefined, true);
|
|
149
|
+
const nativeStartup = configureClaudeNativeStartup(undefined, true);
|
|
150
|
+
const agentPolicy = configureClaudeAgentPolicy(undefined, true);
|
|
151
|
+
if (projectMcpMigration.status === 'would-remove') {
|
|
152
|
+
console.log(`• Claude Code: would remove exact legacy project Prism registration (${projectMcpMigration.path})`);
|
|
153
|
+
}
|
|
154
|
+
if (hookMigration.status === 'would-remove') {
|
|
155
|
+
console.log(`• Claude Code: would remove ${hookMigration.removed} legacy Prism hook action(s) (${hookMigration.path})`);
|
|
156
|
+
}
|
|
157
|
+
if (instructionMigration.status === 'would-remove') {
|
|
158
|
+
console.log(`• Claude Code: would remove ${instructionMigration.removed} legacy Prism startup section(s) (${instructionMigration.path})`);
|
|
159
|
+
}
|
|
160
|
+
if (managedMigration.status === 'would-remove') {
|
|
161
|
+
console.log(`• Claude Code: would remove legacy managed startup block (${managedMigration.path})`);
|
|
162
|
+
}
|
|
163
|
+
if (nativeStartup.status === 'would-install' || nativeStartup.status === 'would-refresh') {
|
|
164
|
+
console.log(`• Claude Code: would ${nativeStartup.status === 'would-install' ? 'install' : 'refresh'} native startup instructions (${nativeStartup.path})`);
|
|
165
|
+
}
|
|
166
|
+
if (agentPolicy.status === 'would-install' || agentPolicy.status === 'would-refresh') {
|
|
167
|
+
console.log(`• Claude Code: would ${agentPolicy.status === 'would-install' ? 'install' : 'refresh'} local-first fallback policy (${agentPolicy.path})`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (connectedGemini) {
|
|
171
|
+
const nativeStartup = configureGeminiNativeStartup(undefined, true);
|
|
172
|
+
const agentPolicy = configureGeminiAgentPolicy(undefined, true);
|
|
173
|
+
if (nativeStartup.status === 'would-install' || nativeStartup.status === 'would-refresh') {
|
|
174
|
+
console.log(`• Gemini CLI: would ${nativeStartup.status === 'would-install' ? 'install' : 'refresh'} native startup instructions (${nativeStartup.path})`);
|
|
175
|
+
}
|
|
176
|
+
if (agentPolicy.status === 'would-install' || agentPolicy.status === 'would-refresh') {
|
|
177
|
+
console.log(`• Gemini CLI: would ${agentPolicy.status === 'would-install' ? 'disable native agents for' : 'refresh'} local-first policy (${agentPolicy.path})`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (connectedCodex) {
|
|
181
|
+
const nativeStartup = configureCodexNativeStartup(undefined, true);
|
|
182
|
+
const agentPolicy = configureCodexAgentPolicy(undefined, true);
|
|
183
|
+
if (nativeStartup.status === 'would-install' || nativeStartup.status === 'would-refresh') {
|
|
184
|
+
console.log(`• Codex: would ${nativeStartup.status === 'would-install' ? 'install' : 'refresh'} native startup instructions (${nativeStartup.path})`);
|
|
185
|
+
}
|
|
186
|
+
if (agentPolicy.status === 'would-install' || agentPolicy.status === 'would-refresh') {
|
|
187
|
+
console.log(`• Codex: would ${agentPolicy.status === 'would-install' ? 'install' : 'refresh'} hard local-first agent limits (${agentPolicy.path})`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
67
190
|
console.log('\nDry run complete — no files changed.');
|
|
68
191
|
}
|
|
192
|
+
else if (summary.results.some((result) => result.status !== 'error' && result.startupCompatible)) {
|
|
193
|
+
// Codex discovers native skills before it starts MCP servers. Syncing
|
|
194
|
+
// only from server startup therefore makes a fresh install require a
|
|
195
|
+
// second host restart. Materialize the entitlement snapshot before
|
|
196
|
+
// this registration command exits so the first launch sees it.
|
|
197
|
+
const { triggerSkillManifestSync } = await import('./skillManifestSync.js');
|
|
198
|
+
const skillSync = await triggerSkillManifestSync();
|
|
199
|
+
if (skillSync.status === 'failed' || skillSync.status === 'partial') {
|
|
200
|
+
throw new Error(`Synalux skill synchronization failed: ${skillSync.error || skillSync.status}`);
|
|
201
|
+
}
|
|
202
|
+
if (skillSync.status !== 'disabled') {
|
|
203
|
+
const changed = skillSync.installed.length + skillSync.updated.length + skillSync.pruned.length;
|
|
204
|
+
console.log(`✓ Synalux skills: ${skillSync.tier || 'free'} tier (${changed} changed)`);
|
|
205
|
+
if (skillSync.conflicts.length > 0) {
|
|
206
|
+
console.error(`⚠ Preserved locally modified skill conflicts: ${skillSync.conflicts.join(', ')}`);
|
|
207
|
+
}
|
|
208
|
+
if (connectedClaude) {
|
|
209
|
+
// Validate every affected surface before mutating any file.
|
|
210
|
+
migrateLegacyClaudeHooks(undefined, true);
|
|
211
|
+
migrateLegacyClaudeInstructions(undefined, true);
|
|
212
|
+
migrateLegacyClaudeManagedStartup(undefined, true);
|
|
213
|
+
configureClaudeNativeStartup(undefined, true);
|
|
214
|
+
configureClaudeAgentPolicy(undefined, true);
|
|
215
|
+
// Install the canonical block first. Never remove the legacy block
|
|
216
|
+
// unless the canonical path is already current or commits safely.
|
|
217
|
+
const nativeStartup = configureClaudeNativeStartup();
|
|
218
|
+
const agentPolicy = configureClaudeAgentPolicy();
|
|
219
|
+
const projectMcpMigration = migrateLegacyClaudeProjectMcp();
|
|
220
|
+
const hookMigration = migrateLegacyClaudeHooks();
|
|
221
|
+
const instructionMigration = migrateLegacyClaudeInstructions();
|
|
222
|
+
const managedMigration = migrateLegacyClaudeManagedStartup();
|
|
223
|
+
if (projectMcpMigration.status === 'removed') {
|
|
224
|
+
console.log(`✓ Claude Code: removed exact legacy project Prism registration (${projectMcpMigration.path}); user-scope registration now owns Prism`);
|
|
225
|
+
}
|
|
226
|
+
if (hookMigration.status === 'removed') {
|
|
227
|
+
console.log(`✓ Claude Code: removed ${hookMigration.removed} legacy Prism hook action(s); native skills now own startup and sync`);
|
|
228
|
+
}
|
|
229
|
+
if (instructionMigration.status === 'removed') {
|
|
230
|
+
console.log(`✓ Claude Code: removed ${instructionMigration.removed} legacy Prism startup section(s); MCP bootstrap now owns first-turn context`);
|
|
231
|
+
}
|
|
232
|
+
if (managedMigration.status === 'removed') {
|
|
233
|
+
console.log('✓ Claude Code: removed legacy managed startup block from ~/CLAUDE.md');
|
|
234
|
+
}
|
|
235
|
+
if (nativeStartup.status === 'installed' || nativeStartup.status === 'refreshed') {
|
|
236
|
+
console.log(`✓ Claude Code: ${nativeStartup.status} hook-free native startup instructions`);
|
|
237
|
+
}
|
|
238
|
+
if (agentPolicy.status === 'installed' || agentPolicy.status === 'refreshed') {
|
|
239
|
+
console.log(`✓ Claude Code: ${agentPolicy.status} local-first policy with Sonnet fallback`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (connectedGemini) {
|
|
243
|
+
configureGeminiNativeStartup(undefined, true);
|
|
244
|
+
configureGeminiAgentPolicy(undefined, true);
|
|
245
|
+
const nativeStartup = configureGeminiNativeStartup();
|
|
246
|
+
const agentPolicy = configureGeminiAgentPolicy();
|
|
247
|
+
if (nativeStartup.status === 'installed' || nativeStartup.status === 'refreshed') {
|
|
248
|
+
console.log(`✓ Gemini CLI: ${nativeStartup.status} hook-free native startup instructions`);
|
|
249
|
+
}
|
|
250
|
+
if (agentPolicy.status === 'installed' || agentPolicy.status === 'refreshed') {
|
|
251
|
+
console.log(`✓ Gemini CLI: ${agentPolicy.status} local-first policy; native agents disabled`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (connectedCodex) {
|
|
255
|
+
configureCodexNativeStartup(undefined, true);
|
|
256
|
+
configureCodexAgentPolicy(undefined, true);
|
|
257
|
+
const nativeStartup = configureCodexNativeStartup();
|
|
258
|
+
const agentPolicy = configureCodexAgentPolicy();
|
|
259
|
+
if (nativeStartup.status === 'installed' || nativeStartup.status === 'refreshed') {
|
|
260
|
+
console.log(`✓ Codex: ${nativeStartup.status} hook-free native startup instructions`);
|
|
261
|
+
}
|
|
262
|
+
if (agentPolicy.status === 'installed' || agentPolicy.status === 'refreshed') {
|
|
263
|
+
console.log(`✓ Codex: ${agentPolicy.status} hard local-first agent limits`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
else if (connectedClaude) {
|
|
268
|
+
// The project-level npx registration is redundant once the
|
|
269
|
+
// user-level installed-server entry succeeds. Removing that exact
|
|
270
|
+
// legacy tuple is independent of native skill delivery; leave hooks
|
|
271
|
+
// and startup instructions untouched while synchronization is off.
|
|
272
|
+
const projectMcpMigration = migrateLegacyClaudeProjectMcp();
|
|
273
|
+
if (projectMcpMigration.status === 'removed') {
|
|
274
|
+
console.log(`✓ Claude Code: removed exact legacy project Prism registration (${projectMcpMigration.path}); user-scope registration now owns Prism`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
69
278
|
if (!summary.usedApiKey) {
|
|
70
279
|
console.log('PRISM_SYNALUX_API_KEY is not set; no Synalux subscription key was copied into new registrations.');
|
|
71
280
|
}
|
|
@@ -101,13 +310,13 @@ program
|
|
|
101
310
|
program
|
|
102
311
|
.command('load <project>')
|
|
103
312
|
.description('Load session context for a project (same output as session_load_context MCP tool)')
|
|
104
|
-
.option('-l, --level <level>', 'Context depth: quick, standard, deep
|
|
313
|
+
.option('-l, --level <level>', 'Context depth: quick, standard, deep (defaults to dashboard setting)')
|
|
105
314
|
.option('-r, --role <role>', 'Role scope for context loading')
|
|
106
315
|
.option('-s, --storage <backend>', 'Storage backend: auto (default, prefers cloud), local (SQLite), or supabase. Overrides PRISM_STORAGE env var.')
|
|
107
316
|
.option('--json', 'Emit machine-readable JSON instead of formatted text')
|
|
108
317
|
.action(async (project, options) => {
|
|
109
318
|
try {
|
|
110
|
-
const { level, role, storage, json: jsonOutput } = options;
|
|
319
|
+
const { level: requestedLevel, role, storage, json: jsonOutput } = options;
|
|
111
320
|
// v9.2.2: --storage flag overrides PRISM_STORAGE env var to prevent
|
|
112
321
|
// split-brain when CLI environment differs from MCP server config.
|
|
113
322
|
if (storage) {
|
|
@@ -119,10 +328,12 @@ program
|
|
|
119
328
|
process.env.PRISM_STORAGE = storage;
|
|
120
329
|
}
|
|
121
330
|
const validLevels = ['quick', 'standard', 'deep'];
|
|
122
|
-
if (!validLevels.includes(
|
|
123
|
-
console.error(`Error: Invalid level "${
|
|
331
|
+
if (requestedLevel && !validLevels.includes(requestedLevel)) {
|
|
332
|
+
console.error(`Error: Invalid level "${requestedLevel}". Must be one of: ${validLevels.join(', ')}`);
|
|
124
333
|
process.exit(1);
|
|
125
334
|
}
|
|
335
|
+
const configuredLevel = requestedLevel ?? await getSetting('default_context_depth', 'standard');
|
|
336
|
+
const level = validLevels.includes(configuredLevel) ? configuredLevel : 'standard';
|
|
126
337
|
if (jsonOutput) {
|
|
127
338
|
// ── JSON mode: structured output for programmatic consumption ──
|
|
128
339
|
const storageBackend = await getStorage();
|
|
@@ -136,30 +347,13 @@ program
|
|
|
136
347
|
}
|
|
137
348
|
const d = data;
|
|
138
349
|
const gitState = getCurrentGitState();
|
|
139
|
-
const output = {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
active_decisions: d.active_decisions || null,
|
|
147
|
-
keywords: d.keywords || null,
|
|
148
|
-
key_context: d.key_context || null,
|
|
149
|
-
active_branch: d.active_branch || null,
|
|
150
|
-
version: d.version ?? null,
|
|
151
|
-
updated_at: d.updated_at || null,
|
|
152
|
-
}],
|
|
153
|
-
recent_ledger: (d.recent_sessions || []).map((s) => ({
|
|
154
|
-
summary: s.summary || null,
|
|
155
|
-
decisions: s.decisions || null,
|
|
156
|
-
keywords: s.keywords || null,
|
|
157
|
-
created_at: s.session_date || s.created_at || null,
|
|
158
|
-
})),
|
|
159
|
-
git_hash: gitState.commitSha ? gitState.commitSha.substring(0, 7) : null,
|
|
160
|
-
git_branch: gitState.branch || null,
|
|
161
|
-
pkg_version: SERVER_CONFIG.version,
|
|
162
|
-
};
|
|
350
|
+
const output = buildLoadJsonOutput(project, d, level, {
|
|
351
|
+
agentName,
|
|
352
|
+
effectiveRole,
|
|
353
|
+
gitHash: gitState.commitSha ? gitState.commitSha.substring(0, 7) : null,
|
|
354
|
+
gitBranch: gitState.branch || null,
|
|
355
|
+
packageVersion: SERVER_CONFIG.version,
|
|
356
|
+
});
|
|
163
357
|
console.log(JSON.stringify(output, null, 2));
|
|
164
358
|
}
|
|
165
359
|
else {
|
|
@@ -167,7 +361,7 @@ program
|
|
|
167
361
|
// Delegates to the real handler so all enrichments (morning briefing,
|
|
168
362
|
// reality drift, SDM recall, visual memory, skill injection,
|
|
169
363
|
// behavioral warnings, etc.) are included automatically.
|
|
170
|
-
const result = await sessionLoadContextHandler({ project, level, role });
|
|
364
|
+
const result = await sessionLoadContextHandler({ project, ...(requestedLevel ? { level: requestedLevel } : {}), role });
|
|
171
365
|
// Surface handler-level errors (e.g. invalid args, storage failures)
|
|
172
366
|
if (result.isError) {
|
|
173
367
|
console.error(result.content[0]?.text || 'Unknown error loading context');
|
|
@@ -646,4 +840,17 @@ program
|
|
|
646
840
|
if (fail > 0)
|
|
647
841
|
process.exit(1);
|
|
648
842
|
});
|
|
649
|
-
|
|
843
|
+
if (process.argv[2] === 'browser') {
|
|
844
|
+
try {
|
|
845
|
+
const exitCode = await runBrowserCli(process.argv.slice(3));
|
|
846
|
+
if (exitCode !== 0)
|
|
847
|
+
process.exitCode = exitCode;
|
|
848
|
+
}
|
|
849
|
+
catch (err) {
|
|
850
|
+
console.error(`Prism Browser failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
851
|
+
process.exitCode = 1;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
await program.parseAsync(process.argv);
|
|
856
|
+
}
|
package/dist/config.js
CHANGED
|
@@ -125,7 +125,9 @@ export const SUPABASE_CONFIGURED = !!SUPABASE_URL &&
|
|
|
125
125
|
// becomes a thin HTTP client of the synalux portal. This is the paid-tier
|
|
126
126
|
// default. Synalux portal owns project validation, tier gating, audit logs,
|
|
127
127
|
// and hivemind agent coordination.
|
|
128
|
-
|
|
128
|
+
// PRISM_SYNALUX_BASE_URL is canonical. SYNALUX_BASE_URL remains a legacy
|
|
129
|
+
// compatibility alias so every portal client resolves the same origin.
|
|
130
|
+
export const PRISM_SYNALUX_BASE_URL = sanitizeEnv(process.env.PRISM_SYNALUX_BASE_URL || process.env.SYNALUX_BASE_URL);
|
|
129
131
|
export const PRISM_SYNALUX_API_KEY = sanitizeEnv(process.env.PRISM_SYNALUX_API_KEY);
|
|
130
132
|
export const SYNALUX_CONFIGURED = !!PRISM_SYNALUX_BASE_URL &&
|
|
131
133
|
!!PRISM_SYNALUX_API_KEY &&
|
|
@@ -264,14 +266,18 @@ export const PRISM_ACTR_BUFFER_FLUSH_MS = parseInt(process.env.PRISM_ACTR_BUFFER
|
|
|
264
266
|
export const PRISM_ACTR_ACCESS_LOG_RETENTION_DAYS = parseInt(process.env.PRISM_ACTR_ACCESS_LOG_RETENTION_DAYS || "90", 10);
|
|
265
267
|
// ─── v7.1: Task Router Configuration ─────────────────────────
|
|
266
268
|
// Deterministic heuristic-based routing for delegating coding tasks
|
|
267
|
-
// between the host cloud model and
|
|
268
|
-
//
|
|
269
|
+
// between the host cloud model and Prism's local worker. Local-first is the
|
|
270
|
+
// default; set PRISM_TASK_ROUTER_ENABLED=false for an explicit operator opt-out.
|
|
269
271
|
/** Master switch for the task router tool. */
|
|
270
|
-
export const PRISM_TASK_ROUTER_ENABLED_ENV = process.env.PRISM_TASK_ROUTER_ENABLED
|
|
272
|
+
export const PRISM_TASK_ROUTER_ENABLED_ENV = process.env.PRISM_TASK_ROUTER_ENABLED !== "false";
|
|
271
273
|
/** Confidence threshold below which routing defaults to the host model. (Default: 0.6) */
|
|
272
274
|
export const PRISM_TASK_ROUTER_CONFIDENCE_THRESHOLD = parseFloat(process.env.PRISM_TASK_ROUTER_CONFIDENCE_THRESHOLD || "0.6");
|
|
273
|
-
/**
|
|
274
|
-
|
|
275
|
+
/**
|
|
276
|
+
* Operator ceiling for bounded local work (1-10). The router independently
|
|
277
|
+
* rejects architecture, security, tool-heavy, and other host-only work.
|
|
278
|
+
* Default 10 lets prism_infer select every entitled/RAM-safe local tier.
|
|
279
|
+
*/
|
|
280
|
+
export const PRISM_TASK_ROUTER_MAX_CLAW_COMPLEXITY = parseInt(process.env.PRISM_TASK_ROUTER_MAX_CLAW_COMPLEXITY || "10", 10);
|
|
275
281
|
// ─── v7.2: Verification Harness ──────────────────────────────
|
|
276
282
|
/** Master switch for the v7.2.0 enhanced verification harness. */
|
|
277
283
|
export const PRISM_VERIFICATION_HARNESS_ENABLED = process.env.PRISM_VERIFICATION_HARNESS_ENABLED === "true";
|