prism-mcp-server 20.5.1 → 20.5.2

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.
@@ -96,10 +96,50 @@ const MAX_SYMPTOM_SKILLS = 5;
96
96
  */
97
97
  const SYMPTOM_SKILL_INLINE_MAX = 1_800;
98
98
  const SYMPTOM_SKILL_BUDGET_SHARE = 0.4;
99
+ /** Below this the inlined rule is too clipped to be worth the space it costs. */
100
+ const SYMPTOM_SKILL_INLINE_MIN = 400;
101
+ /**
102
+ * The character budget a native startup display will actually be capped to.
103
+ *
104
+ * Single source of truth: capNativeStartupText caps against this, and the
105
+ * inlined rule is sized from it. Sizing the rule from the LEVEL constant
106
+ * instead let the suffix exceed the whole allowance — bootstrap divides the
107
+ * budget across rendered projects, so a per-project slice of 512 against an
108
+ * 1,800-char exempt suffix produced a 1,919-char display (275% over) with the
109
+ * session context entirely gone. The suffix is truncation-exempt by design;
110
+ * that only works if it is sized against the real budget.
111
+ */
112
+ function effectiveNativeBudget(level, requestedMaxChars) {
113
+ const configuredLimit = NATIVE_STARTUP_MAX_CHARS[level];
114
+ return Math.max(512, Math.min(configuredLimit, requestedMaxChars ?? configuredLimit));
115
+ }
99
116
  // Skill bodies are read via skillManifestSync.readNativeSkillBody, which owns
100
117
  // the canonical root. That path is overridable per caller and per home, so a
101
118
  // literal copied to this module would be wrong on any machine that overrides
102
119
  // either — and would silently drift from the writer.
120
+ /**
121
+ * Drop the YAML frontmatter before inlining.
122
+ *
123
+ * `name`/`description`/`metadata` are routing and authoring metadata — the
124
+ * agent already has the name from the line above, and the rest is provenance.
125
+ * Measured at ~161 chars on data-before-code, which is what pushed the
126
+ * Anti-Patterns list past the cap and truncated it mid-word. Every character
127
+ * here is taken from the rule it is supposed to deliver.
128
+ *
129
+ * Returns "" for absent input so the caller's single truthiness check covers
130
+ * both "no body" and "frontmatter only".
131
+ */
132
+ function stripSkillFrontmatter(raw) {
133
+ const text = (raw ?? "").trim();
134
+ if (!text.startsWith("---"))
135
+ return text;
136
+ // Closing fence must be its own line; a body line of "---" mid-document is
137
+ // not a terminator, so anchor on the newline pair.
138
+ const end = text.indexOf("\n---", 3);
139
+ if (end === -1)
140
+ return text; // unterminated frontmatter — inline as-is
141
+ return text.slice(text.indexOf("\n", end + 1) + 1).trim();
142
+ }
103
143
  const NATIVE_STARTUP_MAX_CHARS = {
104
144
  quick: 4_000,
105
145
  standard: 8_000,
@@ -266,8 +306,7 @@ async function buildNativeSystemReadyBlock(snapshot, depth) {
266
306
  `> - 🔄 **Skill sync:** ${SKILL_SYNC_STATUS_LABELS[snapshot.syncStatus]} · committed manifest${conflictSuffix}`;
267
307
  }
268
308
  function capNativeStartupText(text, level, requestedMaxChars, suffix = "") {
269
- const configuredLimit = NATIVE_STARTUP_MAX_CHARS[level];
270
- const maxChars = Math.max(512, Math.min(configuredLimit, requestedMaxChars ?? configuredLimit));
309
+ const maxChars = effectiveNativeBudget(level, requestedMaxChars);
271
310
  if (text.length + suffix.length <= maxChars)
272
311
  return text + suffix;
273
312
  const marker = `\n\n… Additional ${level} context omitted to keep native startup within its display budget.`;
@@ -1290,9 +1329,13 @@ export async function sessionLoadContextHandler(args, options = {}) {
1290
1329
  // the content — no MCP tool serves it. Three instruction rewrites
1291
1330
  // failed on that gap. Inlining removes the indirection entirely.
1292
1331
  const { readNativeSkillBody } = await import("../skillManifestSync.js");
1293
- const body = (await readNativeSkillBody(shown[0]))?.trim();
1294
- if (body) {
1295
- const cap = Math.min(SYMPTOM_SKILL_INLINE_MAX, Math.floor(NATIVE_STARTUP_MAX_CHARS[level] * SYMPTOM_SKILL_BUDGET_SHARE));
1332
+ const body = stripSkillFrontmatter(await readNativeSkillBody(shown[0]));
1333
+ // Size against the budget this display will ACTUALLY be capped to,
1334
+ // not the level constant — bootstrap divides it across projects.
1335
+ const cap = Math.min(SYMPTOM_SKILL_INLINE_MAX, Math.floor(effectiveNativeBudget(level, options.nativeMaxChars) * SYMPTOM_SKILL_BUDGET_SHARE));
1336
+ // Too tight to carry a useful rule: keep the name line, which is
1337
+ // small, and leave the remaining budget to the session context.
1338
+ if (body && cap >= SYMPTOM_SKILL_INLINE_MIN) {
1296
1339
  const clipped = body.length > cap
1297
1340
  ? `${body.slice(0, cap).trimEnd()}\n… (rule truncated to fit the startup budget)`
1298
1341
  : body;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prism-mcp-server",
3
- "version": "20.5.1",
3
+ "version": "20.5.2",
4
4
  "mcpName": "io.github.dcostenco/prism-coder",
5
5
  "description": "Prism Coder — Cognitive memory + tool-calling intelligence for AI agents. Mind Palace persistent memory (BFCL Gold Certified, 100% Tool-Call Accuracy, 114 Agent Skills, PHI Guard, Tier Enforcement, Prompt-Based Skill Routing, Zero-Search HDC/HRR retrieval, HRR Semantic Drift Detection across BCBA/Coding/AAC domains, HIPAA-hardened local or subscription-gated Synalux storage, SLERP-optimized GRPO alignment) plus the prism-coder 1.7B–32B open-weights LLM fleet.",
6
6
  "module": "index.ts",