@productbrain/mcp 0.0.1-beta.8560 → 0.0.1-beta.8563

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.
@@ -38,7 +38,7 @@ import {
38
38
  trackQualityVerdict,
39
39
  trackSessionCaptureRate,
40
40
  trackZeroCaptureAuditFired
41
- } from "./chunk-UPQW54GN.js";
41
+ } from "./chunk-FB2VAQOX.js";
42
42
 
43
43
  // src/server.ts
44
44
  import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -144,8 +144,8 @@ var GATE_PATTERNS = [
144
144
  {
145
145
  pattern: /orientation required|call.*orient/i,
146
146
  code: "ORIENTATION_REQUIRED",
147
- recovery: "Orient before writing.",
148
- action: { tool: "orient", description: "Orient session", parameters: {} }
147
+ recovery: "Run orient with a task, then retry.",
148
+ action: { tool: "orient", description: "Orient with a task", parameters: { action: "task" } }
149
149
  },
150
150
  {
151
151
  pattern: /read.?only.*scope/i,
@@ -154,6 +154,13 @@ var GATE_PATTERNS = [
154
154
  action: { tool: "workspace", description: "Check key scope", parameters: { action: "whoami" } }
155
155
  }
156
156
  ];
157
+ function orientationRefusal(err) {
158
+ const gate = GATE_PATTERNS.find((g) => g.code === "ORIENTATION_REQUIRED");
159
+ const mcpErr = asKernelCallError(err);
160
+ const message = mcpErr?.cleanMessage ?? (err instanceof Error ? err.message : String(err));
161
+ if (!gate || !gate.pattern.test(message)) return null;
162
+ return { code: gate.code, message, recovery: gate.recovery, availableActions: [gate.action] };
163
+ }
157
164
  function classifyError(err) {
158
165
  const message = err instanceof Error ? err.message : String(err);
159
166
  if (err instanceof GateError) {
@@ -361,6 +368,13 @@ function thinWrapper(handler) {
361
368
  }
362
369
  };
363
370
  }
371
+ function orientationRefusalResult(err, lines) {
372
+ const refused = orientationRefusal(err);
373
+ if (!refused) return null;
374
+ const text = [...lines, `**${refused.message}**`, "", refused.recovery ?? ""].join("\n");
375
+ return { content: textContent(text), structuredContent: failure(refused.code, refused.message, refused.recovery, refused.availableActions) };
376
+ }
377
+ var ORIENT_REQUIRED_NOTE = "workflow checkpoints and organisation-structure writes (membership, ownership, parent) still require an oriented session.";
364
378
 
365
379
  // src/tools/knowledge-helpers.ts
366
380
  import { z as z2 } from "zod/v3";
@@ -8318,7 +8332,7 @@ function taskGroundingWarningLines(task, hasTaskGrounding = false) {
8318
8332
  if (task) {
8319
8333
  return [
8320
8334
  "## Task grounding incomplete",
8321
- "_A task was provided, but task-scoped governance/context did not load. nothing in the Chain matched it._",
8335
+ "_A task was provided, but task-scoped governance/context did not load. Nothing in the Chain matched it._",
8322
8336
  "",
8323
8337
  'Refine the task and rerun `orient task="describe the work"` or use `context action="gather"` for deeper task context.',
8324
8338
  ""
@@ -8351,7 +8365,7 @@ function registerOrientTool(server) {
8351
8365
  "orient",
8352
8366
  {
8353
8367
  title: "Orient",
8354
- description: "Workspace orientation and session bootstrapping. Two actions:\n\n- **start**: Universal opener (absorbs `start_pb`) \u2014 say 'Start PB' to begin every session. Returns a standup briefing for every workspace state, fresh or active. Orients the CURRENT session \u2014 it does not create one; for writes, call `session action=start` first.\n- **task**: Task-grounded context loader (the original `orient` behavior). Use after `action=start` to load governance and context for a specific task. Completing orientation unlocks write tools.\n\n**tier** (action=task): Controls payload depth.\n- `summary` (~10 KB) \u2014 compact, calibrated for task-scoped retrieval.\n- `standard` (~256 KB) \u2014 rich, suited to workspace standups.\n- `full` \u2014 complete payload, no cap. Use with deliberation.\n\nThe spine (vision, purpose, strategy highlights) is served in full and a grounding status flags when context was reduced.\n\nDefaults: `summary` when `task` is provided; `standard` when `task` is absent. Explicit `tier` always wins.\n\n**mode** (action=task): `full` (default) returns full context. `brief` returns compact summary \u2014 mapped to tier=summary internally.",
8368
+ description: "Workspace orientation and session bootstrapping. Two actions:\n\n- **start**: Universal opener (absorbs `start_pb`) \u2014 say 'Start PB' to begin every session. Returns a standup briefing for every workspace state, fresh or active. Orients the CURRENT session \u2014 it does not create one; for writes, call `session action=start` first.\n- **task**: Task-grounded context loader (the original `orient` behavior). Use after `action=start` to load governance and context for a specific task. Orient is advice for captures, relations, accepts, ticks and questions; " + ORIENT_REQUIRED_NOTE + "\n\n**tier** (action=task): Controls payload depth.\n- `summary` (~10 KB) \u2014 compact, calibrated for task-scoped retrieval.\n- `standard` (~256 KB) \u2014 rich, suited to workspace standups.\n- `full` \u2014 complete payload, no cap. Use with deliberation.\n\nThe spine (vision, purpose, strategy highlights) is served in full and a grounding status flags when context was reduced.\n\nDefaults: `summary` when `task` is provided; `standard` when `task` is absent. Explicit `tier` always wins.\n\n**mode** (action=task): `full` (default) returns full context. `brief` returns compact summary \u2014 mapped to tier=summary internally.",
8355
8369
  inputSchema: orientSchema,
8356
8370
  // Mixed read/write noun (§3 R3): 'start' writes session state.
8357
8371
  annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false }
@@ -8589,7 +8603,7 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
8589
8603
  } else if (agentSessionId) {
8590
8604
  orientationStatus2 = "task_required";
8591
8605
  lines.push("---");
8592
- lines.push('Workspace orientation loaded. Write tools stay locked until you run `orient task="describe the work"`.');
8606
+ lines.push('Workspace orientation loaded. Run `orient task="describe the work"` for task-shaped governance before substantive work; ' + ORIENT_REQUIRED_NOTE);
8593
8607
  } else {
8594
8608
  lines.push("---");
8595
8609
  lines.push("_No active agent session. Call `session action=start` to begin._");
@@ -8974,7 +8988,7 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
8974
8988
  } else if (agentSessionId) {
8975
8989
  orientationStatus = "task_required";
8976
8990
  lines.push("---");
8977
- lines.push('Workspace orientation loaded. Write tools stay locked until you run `orient task="describe the work"`.');
8991
+ lines.push('Workspace orientation loaded. Run `orient task="describe the work"` for task-shaped governance before substantive work; ' + ORIENT_REQUIRED_NOTE);
8978
8992
  } else {
8979
8993
  lines.push("---");
8980
8994
  lines.push("_No active agent session. Call `session action=start` to begin a tracked session._");
@@ -10454,6 +10468,8 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
10454
10468
  )
10455
10469
  };
10456
10470
  } catch (err) {
10471
+ const refusal = orientationRefusalResult(err, lines);
10472
+ if (refusal) return refusal;
10457
10473
  const msg = err instanceof Error ? err.message : String(err);
10458
10474
  lines.push(
10459
10475
  `**Chain accept failed**: ${msg}`,
@@ -10553,12 +10569,10 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
10553
10569
  )
10554
10570
  };
10555
10571
  } catch (err) {
10572
+ const refusal = orientationRefusalResult(err, lines);
10573
+ if (refusal) return refusal;
10556
10574
  const msg = err instanceof Error ? err.message : String(err);
10557
- lines.push(
10558
- `**Checkpoint persistence failed**: ${msg}`,
10559
- "",
10560
- `The conversation context is preserved, but this round was not saved as a durable workflow checkpoint.`
10561
- );
10575
+ lines.push(`**Checkpoint persistence failed**: ${msg}`, "", "The conversation context is preserved, but this round was not saved as a durable workflow checkpoint.");
10562
10576
  return {
10563
10577
  content: [{ type: "text", text: lines.join("\n") }],
10564
10578
  structuredContent: failure(
@@ -10630,12 +10644,10 @@ async function handleFacilitatedFinalization(wf, descriptor, roundId, normalized
10630
10644
  )
10631
10645
  };
10632
10646
  } catch (err) {
10647
+ const refusal = orientationRefusalResult(err, lines);
10648
+ if (refusal) return refusal;
10633
10649
  const msg = err instanceof Error ? err.message : String(err);
10634
- lines.push(
10635
- `**Finalization failed**: ${msg}`,
10636
- "",
10637
- `The workflow output is preserved in this conversation.`
10638
- );
10650
+ lines.push(`**Finalization failed**: ${msg}`, "", "The workflow output is preserved in this conversation.");
10639
10651
  return {
10640
10652
  content: [{ type: "text", text: lines.join("\n") }],
10641
10653
  structuredContent: failure(
@@ -11994,7 +12006,7 @@ async function handleStart2(data) {
11994
12006
  const result2 = await startAgentSession(data?.role);
11995
12007
  const lines = [];
11996
12008
  lines.push(
11997
- `Session ${result2.sessionId} active. Initiated by ${result2.initiatedBy}. Workspace ${result2.workspaceName}. Scope: ${result2.toolsScope}. Write tools available after orient.`
12009
+ `Session ${result2.sessionId} active. Initiated by ${result2.initiatedBy}. Workspace ${result2.workspaceName}. Scope: ${result2.toolsScope}. Orient with a task before substantive work: it is advice for captures, relations, accepts, ticks and questions; workflow checkpoints and organisation-structure writes still require it.`
11998
12010
  );
11999
12011
  if (result2.roleEntryId) {
12000
12012
  lines.push(`Acting as role: ${result2.roleName ?? result2.roleEntryId}.`);
@@ -12006,7 +12018,7 @@ async function handleStart2(data) {
12006
12018
  }
12007
12019
  const ruleLines = formatRuleListsLines(result2.ruleLists);
12008
12020
  if (ruleLines.length > 0) lines.push("", "Rules:", ...ruleLines);
12009
- const summary = `Session ${result2.sessionId} active. Workspace ${result2.workspaceName}. Write tools available after orient.`;
12021
+ const summary = `Session ${result2.sessionId} active. Workspace ${result2.workspaceName}. Orient with a task first; workflow checkpoints and organisation-structure writes still require it.`;
12010
12022
  return {
12011
12023
  content: [{ type: "text", text: lines.join("\n") }],
12012
12024
  structuredContent: success(summary, {
@@ -14527,4 +14539,4 @@ export {
14527
14539
  createProductBrainServer,
14528
14540
  initFeatureFlags
14529
14541
  };
14530
- //# sourceMappingURL=chunk-SOVY6GZS.js.map
14542
+ //# sourceMappingURL=chunk-6OMZMXSM.js.map