@productbrain/mcp 0.0.1-beta.3409 → 0.0.1-beta.3413

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.
@@ -8513,6 +8513,71 @@ function formatShapeAdvisorySummaryLine(sas) {
8513
8513
  return `Shape advisories (${sas.windowDays}d): ${sas.pendingCount} pending / ${sas.compoundTotal} compound${pendingRatePart} \u2014 precisionAgent ${agentPart}, precisionHuman ${humanPart}.${truncatedNote}${candidatePart}`;
8514
8514
  }
8515
8515
 
8516
+ // src/tools/orient-rituals.ts
8517
+ function buildRitualsSurfaceLines(view, opts) {
8518
+ const lines = [""];
8519
+ if (opts?.fetchFailed) {
8520
+ lines.push("Direction: unavailable \u2014 orient fetch failed, retry `orient`");
8521
+ lines.push("Spine check: unavailable \u2014 orient fetch failed, retry `orient`");
8522
+ return lines;
8523
+ }
8524
+ lines.push(view?.directionLine ?? "Direction: not computed yet \u2014 `pb direction refresh`");
8525
+ if (view?.verdictAskLine) lines.push(view.verdictAskLine);
8526
+ lines.push(view?.spineLine ?? "Spine check: not computed yet \u2014 `pb quality spine-check`");
8527
+ return lines;
8528
+ }
8529
+ async function buildAlreadyOrientedResult(kernelQuery2, agentSessionId, taskGroundingWarningLines2) {
8530
+ let ritualsFetchFailed = false;
8531
+ let rituals = null;
8532
+ try {
8533
+ rituals = await kernelQuery2("chain.getRitualsSurface", {});
8534
+ } catch {
8535
+ ritualsFetchFailed = true;
8536
+ }
8537
+ const ritualsLines = buildRitualsSurfaceLines(rituals, { fetchFailed: ritualsFetchFailed });
8538
+ return {
8539
+ content: [{
8540
+ type: "text",
8541
+ text: "Already oriented. Session active, writes unlocked.\n" + ritualsLines.join("\n") + "\n\n" + taskGroundingWarningLines2.join("\n") + "Use `orient mode='full'` for workspace context or `orient task='...'` before substantive work."
8542
+ }],
8543
+ structuredContent: success(
8544
+ "Already oriented. Session active, writes unlocked.",
8545
+ {
8546
+ alreadyOriented: true,
8547
+ sessionId: agentSessionId,
8548
+ taskGroundingStatus: "workspace_only",
8549
+ taskGroundingRequired: true,
8550
+ nextStep: 'Run `orient task="describe the work"` before substantive work.',
8551
+ // T1's undefined-vs-null distinction: omit the key on a fetch failure, keep an explicit
8552
+ // null for a genuine no-row arm.
8553
+ ...rituals?.directionLine !== void 0 ? { directionLine: rituals.directionLine } : {},
8554
+ ...rituals?.verdictAskLine !== void 0 ? { verdictAskLine: rituals.verdictAskLine } : {},
8555
+ ...rituals?.spineLine !== void 0 ? { spineLine: rituals.spineLine } : {}
8556
+ }
8557
+ )
8558
+ };
8559
+ }
8560
+
8561
+ // src/tools/orient-metrics.ts
8562
+ function reportOrientWrapperBytes(toolResult, truncated, tier, taskProvided) {
8563
+ try {
8564
+ const fullToolOutput = JSON.stringify({ content: toolResult.content ?? [] });
8565
+ const bytes = Buffer.byteLength(fullToolOutput, "utf8");
8566
+ const sessionId = getAgentSessionId();
8567
+ const conversationId = getConversationId();
8568
+ void kernelMutation("agent.reportOrientMetric", {
8569
+ bytes,
8570
+ truncated,
8571
+ tier,
8572
+ taskProvided,
8573
+ ...sessionId ? { sessionId } : {},
8574
+ ...conversationId ? { conversationId } : {}
8575
+ }).catch(() => {
8576
+ });
8577
+ } catch {
8578
+ }
8579
+ }
8580
+
8516
8581
  // src/lib/gapToPrompt.ts
8517
8582
  function cleanLabel(label) {
8518
8583
  return label.replace(/ has entries$/i, "").replace(/ coverage$/i, "").replace(/^Strategy — /i, "");
@@ -9015,24 +9080,6 @@ function domainDetailFromRetrieval(retrieval) {
9015
9080
  const evidenceGap = typeof retrieval.evidenceGap === "string" ? retrieval.evidenceGap : null;
9016
9081
  return reason || nextAction || evidenceGap ? { reason, nextAction, evidenceGap } : null;
9017
9082
  }
9018
- function reportOrientWrapperBytes(toolResult, truncated, tier, taskProvided) {
9019
- try {
9020
- const fullToolOutput = JSON.stringify({ content: toolResult.content ?? [] });
9021
- const bytes = Buffer.byteLength(fullToolOutput, "utf8");
9022
- const sessionId = getAgentSessionId();
9023
- const conversationId = getConversationId();
9024
- void kernelMutation("agent.reportOrientMetric", {
9025
- bytes,
9026
- truncated,
9027
- tier,
9028
- taskProvided,
9029
- ...sessionId ? { sessionId } : {},
9030
- ...conversationId ? { conversationId } : {}
9031
- }).catch(() => {
9032
- });
9033
- } catch {
9034
- }
9035
- }
9036
9083
  async function markOrientedWithSnapshotFallback(agentSessionId, coherenceSnapshot) {
9037
9084
  try {
9038
9085
  await kernelCall("agent.markOriented", {
@@ -9194,22 +9241,7 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
9194
9241
  }
9195
9242
  const agentSessionId = getAgentSessionId();
9196
9243
  if (isSessionOriented() && mode === "brief" && !task) {
9197
- return {
9198
- content: [{
9199
- type: "text",
9200
- text: "Already oriented. Session active, writes unlocked.\n\n" + taskGroundingWarningLines().join("\n") + "Use `orient mode='full'` for workspace context or `orient task='...'` before substantive work."
9201
- }],
9202
- structuredContent: success(
9203
- "Already oriented. Session active, writes unlocked.",
9204
- {
9205
- alreadyOriented: true,
9206
- sessionId: agentSessionId,
9207
- taskGroundingStatus: "workspace_only",
9208
- taskGroundingRequired: true,
9209
- nextStep: 'Run `orient task="describe the work"` before substantive work.'
9210
- }
9211
- )
9212
- };
9244
+ return buildAlreadyOrientedResult(kernelQuery, agentSessionId, taskGroundingWarningLines());
9213
9245
  }
9214
9246
  let wsCtx = null;
9215
9247
  try {
@@ -9220,6 +9252,7 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
9220
9252
  let priorSessions = [];
9221
9253
  let recoveryBlock = null;
9222
9254
  let orientView = null;
9255
+ let orientFetchFailed = false;
9223
9256
  try {
9224
9257
  const orientArgs = {};
9225
9258
  if (task) orientArgs.task = task;
@@ -9237,6 +9270,7 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
9237
9270
  if (orientConversationId) orientArgs.conversationId = orientConversationId;
9238
9271
  orientView = await kernelQuery("chain.getOrientView", orientArgs);
9239
9272
  } catch {
9273
+ orientFetchFailed = true;
9240
9274
  }
9241
9275
  const resolvedTier = orientView?.resolvedTier ?? callTier ?? "standard";
9242
9276
  const taskMeaningful = orientView?.taskMeaningful ?? false;
@@ -9360,6 +9394,7 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
9360
9394
  if (orientView?.taskAlignment) {
9361
9395
  lines.push(`Task alignment: ${orientView.taskAlignment.verdict} \u2014 ${orientView.taskAlignment.wording.replace(/\*\*/g, "")}`);
9362
9396
  }
9397
+ lines.push(...buildRitualsSurfaceLines(orientView, { fetchFailed: orientFetchFailed }));
9363
9398
  if (orientView?.startup?.domainRetrieval) {
9364
9399
  const retrieval = orientView.startup.domainRetrieval;
9365
9400
  const scopedTo = retrieval.resolvedDomainSlug ? ` (${retrieval.resolvedDomainSlug})` : "";
@@ -9502,6 +9537,12 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
9502
9537
  ...orientView?.taskContext?.isGroundingStub ? { groundingStub: true } : {},
9503
9538
  // WP-465 slice ③ (§4.1): served verbatim — identical on CLI and MCP.
9504
9539
  ...orientView?.taskAlignment ? { taskAlignment: orientView.taskAlignment } : {},
9540
+ // WP-582 B2 round 1 (Codex P2 review, PR #532, T1): omit when `undefined` (old
9541
+ // deploy, field never served); keep an explicit `null` for the documented no-row
9542
+ // arm — the two states must stay distinguishable to a structuredContent consumer.
9543
+ ...orientView?.directionLine !== void 0 ? { directionLine: orientView.directionLine } : {},
9544
+ ...orientView?.verdictAskLine !== void 0 ? { verdictAskLine: orientView.verdictAskLine } : {},
9545
+ ...orientView?.spineLine !== void 0 ? { spineLine: orientView.spineLine } : {},
9505
9546
  // RCRT miss-alarm: machine-readable verdict for structuredContent
9506
9547
  // consumers (parity with the rendered prose alarm).
9507
9548
  ...orientView?.retrievalMiss ? { retrievalMiss: orientView.retrievalMiss } : {},
@@ -9684,6 +9725,7 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
9684
9725
  }
9685
9726
  if (orientView) {
9686
9727
  lines.push(...buildTaskAlignmentLines(orientView.taskAlignment));
9728
+ lines.push(...buildRitualsSurfaceLines(orientView, { fetchFailed: orientFetchFailed }));
9687
9729
  lines.push(...formatInitiativeStatusLines(orientView.initiativeStatus));
9688
9730
  lines.push(...formatWorkstreamHealthLines(orientView.workstreamHealth));
9689
9731
  lines.push(...formatWhatNeedsAttentionLines(orientView.whatNeedsAttention));
@@ -9811,6 +9853,7 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
9811
9853
  } else {
9812
9854
  lines.push(`**Brain stage: ${orientStage}.**`);
9813
9855
  lines.push("");
9856
+ lines.push(...buildRitualsSurfaceLines(orientView, { fetchFailed: orientFetchFailed }));
9814
9857
  if (orientView?.activeWorkPackages?.length) {
9815
9858
  lines.push("## Active work packages \u2014 current scope");
9816
9859
  lines.push("_Work outside these work packages requires explicit user confirmation._");
@@ -9934,6 +9977,12 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
9934
9977
  ...orientView?.taskContext?.isGroundingStub ? { groundingStub: true } : {},
9935
9978
  // WP-465 slice ③ (§4.1): served verbatim — identical on CLI and MCP.
9936
9979
  ...orientView?.taskAlignment ? { taskAlignment: orientView.taskAlignment } : {},
9980
+ // WP-582 B2 round 1 (Codex P2 review, PR #532, T1): served verbatim ONLY when the
9981
+ // server actually sent the field — see the matching brief-mode comment above for the
9982
+ // undefined-vs-null distinction this preserves.
9983
+ ...orientView?.directionLine !== void 0 ? { directionLine: orientView.directionLine } : {},
9984
+ ...orientView?.verdictAskLine !== void 0 ? { verdictAskLine: orientView.verdictAskLine } : {},
9985
+ ...orientView?.spineLine !== void 0 ? { spineLine: orientView.spineLine } : {},
9937
9986
  // RCRT miss-alarm: machine-readable verdict for structuredContent
9938
9987
  // consumers (parity with the rendered prose alarm).
9939
9988
  ...orientView?.retrievalMiss ? { retrievalMiss: orientView.retrievalMiss } : {},
@@ -13097,6 +13146,12 @@ async function handleClose() {
13097
13146
  `| Contradiction warnings | ${warnings} |`
13098
13147
  );
13099
13148
  }
13149
+ let rituals = null;
13150
+ try {
13151
+ rituals = await kernelCall("chain.getRitualsSurface", {});
13152
+ } catch {
13153
+ }
13154
+ if (rituals) lines.push(...buildRitualsSurfaceLines(rituals));
13100
13155
  lines.push("", "Write tools are now blocked. Session data saved for future orientation.");
13101
13156
  const fullResponse = wrapupNudge + lines.join("\n");
13102
13157
  const summary = `Session ${sessionId} closed. ${created} created, ${modified} modified.`;
@@ -13109,7 +13164,13 @@ async function handleClose() {
13109
13164
  relationsCreated: relations,
13110
13165
  gateFailures: gates,
13111
13166
  contradictionWarnings: warnings,
13112
- wrapupNudge: wrapupNudge.length > 0
13167
+ wrapupNudge: wrapupNudge.length > 0,
13168
+ // T1's undefined-vs-null distinction applies here too — omit the key entirely when the
13169
+ // fetch failed, rather than forcing a null a machine consumer can't distinguish from a
13170
+ // genuine no-row arm.
13171
+ ...rituals?.directionLine !== void 0 ? { directionLine: rituals.directionLine } : {},
13172
+ ...rituals?.verdictAskLine !== void 0 ? { verdictAskLine: rituals.verdictAskLine } : {},
13173
+ ...rituals?.spineLine !== void 0 ? { spineLine: rituals.spineLine } : {}
13113
13174
  })
13114
13175
  };
13115
13176
  }
@@ -16400,4 +16461,4 @@ export {
16400
16461
  createProductBrainServer,
16401
16462
  initFeatureFlags
16402
16463
  };
16403
- //# sourceMappingURL=chunk-3JRSYADK.js.map
16464
+ //# sourceMappingURL=chunk-GFBV6BUO.js.map