@productbrain/mcp 0.0.1-beta.4276 → 0.0.1-beta.4282
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.
|
@@ -9518,7 +9518,7 @@ function registerOrientTool(server) {
|
|
|
9518
9518
|
"orient",
|
|
9519
9519
|
{
|
|
9520
9520
|
title: "Orient",
|
|
9521
|
-
description: "Workspace orientation and session bootstrapping. Three actions:\n\n- **start**: Universal opener (absorbs `start_pb`) \u2014 say 'Start PB' to begin every session. Stage-aware: fresh workspaces (blank/seeded) get the SKILL-pb-setup body verbatim; active workspaces (grounded/connected) get a standup briefing. 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- **record-activation**: Chat-only activation receipt writer (absorbs `record_activation`) \u2014 closes the install-to-activation arc for chat-only surfaces.\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 (
|
|
9521
|
+
description: "Workspace orientation and session bootstrapping. Three actions:\n\n- **start**: Universal opener (absorbs `start_pb`) \u2014 say 'Start PB' to begin every session. Stage-aware: fresh workspaces (blank/seeded) get the SKILL-pb-setup body verbatim; active workspaces (grounded/connected) get a standup briefing. 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- **record-activation**: Chat-only activation receipt writer (absorbs `record_activation`) \u2014 closes the install-to-activation arc for chat-only surfaces.\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, except strategicContext vision/purpose (always server-bounded to ~200 chars + an ellipsis marker \u2014 no uncapped path at any tier). Use with deliberation.\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.\n\n**scope** (action=task): Optional domain scope filtering governance to entries relevant for the specified domain.",
|
|
9522
9522
|
inputSchema: orientSchema,
|
|
9523
9523
|
// Mixed read/write noun (§3 R3): 'start'/'record-activation' write session state.
|
|
9524
9524
|
annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false }
|
|
@@ -9847,9 +9847,7 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
|
|
|
9847
9847
|
...orientView?.taskAlignment ? { taskAlignment: orientView.taskAlignment } : {},
|
|
9848
9848
|
...orientView?.degradedPreloads?.length ? { degradedPreloads: orientView.degradedPreloads } : {},
|
|
9849
9849
|
// WP-621 S1
|
|
9850
|
-
// WP-582 B2 round 1 (Codex P2 review, PR #532, T1): omit when `undefined` (old
|
|
9851
|
-
// deploy, field never served); keep an explicit `null` for the documented no-row
|
|
9852
|
-
// arm — the two states must stay distinguishable to a structuredContent consumer.
|
|
9850
|
+
// WP-582 B2 round 1 (Codex P2 review, PR #532, T1): omit when `undefined` (old deploy, never served); keep explicit `null` for the documented no-row arm — the two states must stay distinguishable to consumers.
|
|
9853
9851
|
...orientView?.directionLine !== void 0 ? { directionLine: orientView.directionLine } : {},
|
|
9854
9852
|
...orientView?.verdictAskLine !== void 0 ? { verdictAskLine: orientView.verdictAskLine } : {},
|
|
9855
9853
|
...orientView?.spineLine !== void 0 ? { spineLine: orientView.spineLine } : {},
|
|
@@ -9857,8 +9855,7 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
|
|
|
9857
9855
|
// PR #538 late review (P2)
|
|
9858
9856
|
...orientView?.fetchFailed !== void 0 ? { fetchFailed: orientView.fetchFailed } : {},
|
|
9859
9857
|
// PR #539 review fix
|
|
9860
|
-
// RCRT miss-alarm: machine-readable verdict for structuredContent
|
|
9861
|
-
// consumers (parity with the rendered prose alarm).
|
|
9858
|
+
// RCRT miss-alarm: machine-readable verdict for structuredContent consumers (parity with the rendered prose alarm).
|
|
9862
9859
|
...orientView?.retrievalMiss ? { retrievalMiss: orientView.retrievalMiss } : {},
|
|
9863
9860
|
orientationStatus: orientationStatus2,
|
|
9864
9861
|
nextStep: hasTaskGrounding ? void 0 : 'Run `orient task="describe the work"` before substantive work.',
|
|
@@ -9886,6 +9883,9 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
|
|
|
9886
9883
|
}
|
|
9887
9884
|
let fullCoherenceSnapshot;
|
|
9888
9885
|
if (isLowReadiness) {
|
|
9886
|
+
const scLR = !task ? orientView?.strategicContext : void 0;
|
|
9887
|
+
const scLRLines = scLR ? [scLR.vision && `**Vision:** ${scLR.vision}`, scLR.purpose && `**Purpose:** ${scLR.purpose}`].filter((l) => Boolean(l)) : [];
|
|
9888
|
+
if (scLRLines.length > 0) lines.push("## Strategic Context", ...scLRLines, "");
|
|
9889
9889
|
const captureBehaviorNote = (readiness?.governanceMode ?? wsCtx?.governanceMode ?? "open") === "open" ? "_In Open mode, captures are accepted automatically unless you ask me to keep them as drafts._" : "_Everything stays as a draft until you confirm._";
|
|
9890
9890
|
const gaps = readiness.gaps ?? [];
|
|
9891
9891
|
if (gaps.length > 0) {
|
|
@@ -9935,12 +9935,8 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
|
|
|
9935
9935
|
lines.push("## Strategic Context");
|
|
9936
9936
|
if (sc.vision) lines.push(`**Vision:** ${sc.vision}`);
|
|
9937
9937
|
if (sc.purpose) lines.push(`**Purpose:** ${sc.purpose}`);
|
|
9938
|
-
if (sc.productAreaCount != null && sc.productAreaCount > 0) {
|
|
9939
|
-
|
|
9940
|
-
}
|
|
9941
|
-
if (sc.playingFieldCount != null && sc.playingFieldCount > 0) {
|
|
9942
|
-
lines.push(`**Playing field (${sc.playingFieldCount}):** ${(sc.playingField ?? []).join(", ")}`);
|
|
9943
|
-
}
|
|
9938
|
+
if (sc.productAreaCount != null && sc.productAreaCount > 0) lines.push(`**Product areas (${sc.productAreaCount}):** ${(sc.productAreas ?? []).join(", ")}`);
|
|
9939
|
+
if (sc.playingFieldCount != null && sc.playingFieldCount > 0) lines.push(`**Playing field (${sc.playingFieldCount}):** ${(sc.playingField ?? []).join(", ")}`);
|
|
9944
9940
|
const currentWP = sc.currentWorkPackage;
|
|
9945
9941
|
const wpSingularFull = getCollectionLabel("work_package", "singular", vocabCtx);
|
|
9946
9942
|
const wpPluralFull = getCollectionLabel("work_package", "plural", vocabCtx);
|
|
@@ -15888,6 +15884,15 @@ function registerShapeTools(server) {
|
|
|
15888
15884
|
|
|
15889
15885
|
// src/tools/question.ts
|
|
15890
15886
|
import { z as z34 } from "zod/v3";
|
|
15887
|
+
|
|
15888
|
+
// src/lib/strip.ts
|
|
15889
|
+
var ANSI_AND_CONTROL_RE2 = /\x1b\[[0-9;]*[A-Za-z]|\x1b\][^\x07]*\x07|\x1b[^[\]0-9;A-Za-z]?|[\x00-\x08\x0b-\x1f\x7f]/g;
|
|
15890
|
+
function stripControlChars(str) {
|
|
15891
|
+
if (!str) return str;
|
|
15892
|
+
return str.replace(ANSI_AND_CONTROL_RE2, "");
|
|
15893
|
+
}
|
|
15894
|
+
|
|
15895
|
+
// src/tools/question.ts
|
|
15891
15896
|
var QUESTION_ACTIONS = ["create", "adopt", "assign", "snooze", "decline", "answer", "force-close", "list"];
|
|
15892
15897
|
var questionSchema = z34.object({
|
|
15893
15898
|
action: z34.enum(QUESTION_ACTIONS).describe(
|
|
@@ -15942,7 +15947,7 @@ async function displayName(id) {
|
|
|
15942
15947
|
if (!id) return void 0;
|
|
15943
15948
|
try {
|
|
15944
15949
|
const entry = await kernelQuery("chain.getEntry", { id });
|
|
15945
|
-
return entry?.name;
|
|
15950
|
+
return entry?.name ? stripControlChars(entry.name) : void 0;
|
|
15946
15951
|
} catch {
|
|
15947
15952
|
return void 0;
|
|
15948
15953
|
}
|
|
@@ -15998,7 +16003,7 @@ async function handleQuestionAssign(entryId, toRole, toPerson) {
|
|
|
15998
16003
|
const isReassign = Boolean(toRole || toPerson);
|
|
15999
16004
|
let message;
|
|
16000
16005
|
if (isReassign) {
|
|
16001
|
-
const who = toPerson ? result2.ownerPersonName ?? result2.ownerPersonId
|
|
16006
|
+
const who = toPerson ? stripControlChars(result2.ownerPersonName ?? "") || result2.ownerPersonId || "the target" : await displayName(result2.ownerRoleId) ?? result2.ownerRoleId ?? "the target";
|
|
16002
16007
|
message = `${entryId} reassigned to ${who}. They'll see it at their next session.`;
|
|
16003
16008
|
} else {
|
|
16004
16009
|
message = `${entryId} is yours now.`;
|
|
@@ -16066,7 +16071,7 @@ async function handleQuestionAnswer(entryId, text, answerEntryId) {
|
|
|
16066
16071
|
const resolvedEntryId = await resolveEntryRef(entryId, "Entry");
|
|
16067
16072
|
const resolvedAnswerEntryId = answerEntryId ? await resolveEntryRef(answerEntryId, "Answer entry") : void 0;
|
|
16068
16073
|
const result2 = await kernelMutation("question.answer", { entryId: resolvedEntryId, text, answerEntryId: resolvedAnswerEntryId });
|
|
16069
|
-
const askerName = result2.askerName
|
|
16074
|
+
const askerName = (result2.askerName ? stripControlChars(result2.askerName) : "") || "The asker";
|
|
16070
16075
|
const pendingNote = result2.answerPending ? " The answer is a draft awaiting accept." : "";
|
|
16071
16076
|
const message = result2.idempotent ? result2.processedVia === "declined" || result2.processedVia === "force_closed" ? `${entryId} is already processed (${result2.processedVia === "declined" ? "declined" : "force-closed"}) \u2014 no change.` : `${entryId} is already answered \u2014 no change.` : `Answered. ${askerName} will see the outcome at their next session (and in pb question list --mine).${pendingNote}`;
|
|
16072
16077
|
return successResult(message, message, result2);
|
|
@@ -16094,8 +16099,8 @@ async function handleQuestionList(mine) {
|
|
|
16094
16099
|
return successResult(message2, message2, { ...result2, action: "list" });
|
|
16095
16100
|
}
|
|
16096
16101
|
const lines = rows.map((r) => {
|
|
16097
|
-
const outcomeSuffix = mine && r.outcome ? ` \u2014 ${r.outcome}` : "";
|
|
16098
|
-
return `[${r.entryId}] ${r.question} \u2014 ${r.stateLabel} \u2014 ${r.why} \u2014 ${r.domain} \u2014 ${r.withLabel} \u2014 ${r.ageDays}d${outcomeSuffix}`;
|
|
16102
|
+
const outcomeSuffix = mine && r.outcome ? ` \u2014 ${stripControlChars(r.outcome)}` : "";
|
|
16103
|
+
return `[${stripControlChars(r.entryId)}] ${stripControlChars(r.question)} \u2014 ${stripControlChars(r.stateLabel)} \u2014 ${stripControlChars(r.why)} \u2014 ${stripControlChars(r.domain)} \u2014 ${stripControlChars(r.withLabel)} \u2014 ${r.ageDays}d${outcomeSuffix}`;
|
|
16099
16104
|
});
|
|
16100
16105
|
const truncationNote = result2.truncated ? `
|
|
16101
16106
|
(${mine ? "showing your most recent questions only \u2014 older ones exist but are not shown" : "this list may be incomplete \u2014 some obligations may not be shown"})` : "";
|
|
@@ -17082,4 +17087,4 @@ export {
|
|
|
17082
17087
|
createProductBrainServer,
|
|
17083
17088
|
initFeatureFlags
|
|
17084
17089
|
};
|
|
17085
|
-
//# sourceMappingURL=chunk-
|
|
17090
|
+
//# sourceMappingURL=chunk-MEQC3IGR.js.map
|