@productbrain/mcp 0.0.1-beta.8637 → 0.0.1-beta.8647
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/dist/{chunk-66OMK2AA.js → chunk-FZWP45AU.js} +1 -1
- package/dist/{chunk-66OMK2AA.js.map → chunk-FZWP45AU.js.map} +1 -1
- package/dist/{chunk-OZXZLLHS.js → chunk-JSKIMDXR.js} +112 -184
- package/dist/chunk-JSKIMDXR.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/http.js +2 -2
- package/dist/index.js +2 -2
- package/dist/{setup-SM4BGXPL.js → setup-YCYGYJNK.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-OZXZLLHS.js.map +0 -1
- /package/dist/{setup-SM4BGXPL.js.map → setup-YCYGYJNK.js.map} +0 -0
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
trackQualityVerdict,
|
|
39
39
|
trackSessionCaptureRate,
|
|
40
40
|
trackZeroCaptureAuditFired
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-FZWP45AU.js";
|
|
42
42
|
|
|
43
43
|
// src/server.ts
|
|
44
44
|
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -7613,23 +7613,68 @@ function formatRuleListsLines(ruleLists) {
|
|
|
7613
7613
|
if (lines.length === 0 && ruleLists.unassigned === 0 && !ruleLists.truncated) return [];
|
|
7614
7614
|
return [...lines, ...formatRuleListTrailers(ruleLists)];
|
|
7615
7615
|
}
|
|
7616
|
+
var BRIEFING_PULL_COMMANDS = {
|
|
7617
|
+
cli: 'pb orient --task "<what you are doing>" \xB7 pb get <ID> \xB7 pb search <query>',
|
|
7618
|
+
mcp: 'orient task="<what you are doing>" \xB7 entries action=get entryId=<ID> \xB7 entries action=search query=<query>'
|
|
7619
|
+
};
|
|
7620
|
+
var BRIEFING_ANSWER_COMMANDS = {
|
|
7621
|
+
cli: 'pb question answer <ID> "<answer>"',
|
|
7622
|
+
mcp: 'question action=answer entryId=<ID> text="<answer>"'
|
|
7623
|
+
};
|
|
7624
|
+
var BRIEFING_QUESTION_DETAIL_COMMANDS = {
|
|
7625
|
+
cli: "pb question list",
|
|
7626
|
+
mcp: "question action=list"
|
|
7627
|
+
};
|
|
7628
|
+
var BRIEFING_QUESTION_MAX_CHARS = 160;
|
|
7629
|
+
function briefingLine(value, max) {
|
|
7630
|
+
const line = sanitizeRuleListField(value);
|
|
7631
|
+
if (max === void 0 || Array.from(line).length <= max) return line;
|
|
7632
|
+
const cut = Array.from(line).slice(0, max).join("");
|
|
7633
|
+
return `${(cut.replace(/\s+\S*$/, "") || cut).trimEnd()}\u2026`;
|
|
7634
|
+
}
|
|
7635
|
+
function idTag(entryId) {
|
|
7636
|
+
return entryId ? ` (${sanitizeRuleListField(entryId)})` : "";
|
|
7637
|
+
}
|
|
7638
|
+
function formatBriefingLines(view) {
|
|
7639
|
+
const lines = [];
|
|
7640
|
+
const f = view.facts ?? {};
|
|
7641
|
+
if (view.workspaceName) lines.push(`Workspace: ${briefingLine(view.workspaceName)}${view.actingRole ? ` \u2014 acting as ${briefingLine(view.actingRole)}` : ""}`);
|
|
7642
|
+
if (f.purpose) lines.push(`Purpose: ${briefingLine(f.purpose)}`);
|
|
7643
|
+
if (f.vision) lines.push(`Vision: ${briefingLine(f.vision)}`);
|
|
7644
|
+
if (f.strategy) {
|
|
7645
|
+
lines.push(`Strategy${idTag(f.strategy.entryId)}: ${briefingLine(f.strategy.name)}`);
|
|
7646
|
+
if (f.strategy.notDo) lines.push(` Not doing: ${briefingLine(f.strategy.notDo)}`);
|
|
7647
|
+
}
|
|
7648
|
+
if (f.objective) {
|
|
7649
|
+
lines.push(`Objective${idTag(f.objective.entryId)}: ${briefingLine(f.objective.name)}`);
|
|
7650
|
+
for (const kr of f.objective.keyResults) {
|
|
7651
|
+
const current = kr.readingUnresolved ? "unresolved (too many corrections to read)" : kr.currentValue ?? "n/a";
|
|
7652
|
+
const value = `${current} / ${kr.targetValue ?? "n/a"}`;
|
|
7653
|
+
lines.push(` - ${briefingLine(kr.name)}: ${value}`);
|
|
7654
|
+
}
|
|
7655
|
+
}
|
|
7656
|
+
if (f.currentWorkPackage) lines.push(`Current work package${idTag(f.currentWorkPackage.entryId)}: ${briefingLine(f.currentWorkPackage.name)}`);
|
|
7657
|
+
if (f.briefingUnavailable) lines.push("Purpose, vision, strategy, objective and work package: unavailable \u2014 the briefing read failed; orient again to retry.");
|
|
7658
|
+
if (f.spineUnavailable) lines.push("Objective: unavailable \u2014 the objectives read failed; orient again to retry.");
|
|
7659
|
+
if (f.truncated) lines.push("(A bounded read hit its cap: a fact above may be missing or not the current one.)");
|
|
7660
|
+
const ruleLines = formatRuleListsLines(view.ruleLists);
|
|
7661
|
+
if (ruleLines.length > 0) lines.push("", "Rules:", ...ruleLines);
|
|
7662
|
+
const questions = view.openQuestions ?? [];
|
|
7663
|
+
if (questions.length > 0) {
|
|
7664
|
+
lines.push("", `Open questions (${questions.length}) \u2014 they need you before you continue; answer with ${BRIEFING_ANSWER_COMMANDS[view.surface]}:`);
|
|
7665
|
+
for (const q of questions) {
|
|
7666
|
+
const age = q.ageDays !== void 0 ? ` (${q.ageDays}d)` : "";
|
|
7667
|
+
lines.push(` - ${sanitizeRuleListField(q.entryId)} \u2014 ${briefingLine(q.title, BRIEFING_QUESTION_MAX_CHARS)}${age}`);
|
|
7668
|
+
}
|
|
7669
|
+
if (view.openQuestionsTruncated) lines.push(" (This list may be incomplete: you may have more open questions than shown.)");
|
|
7670
|
+
lines.push(` Asker, why you, what waits on it and what you may do: ${BRIEFING_QUESTION_DETAIL_COMMANDS[view.surface]}`);
|
|
7671
|
+
}
|
|
7672
|
+
lines.push("", `Pull more: ${BRIEFING_PULL_COMMANDS[view.surface]}`);
|
|
7673
|
+
return lines;
|
|
7674
|
+
}
|
|
7616
7675
|
|
|
7617
7676
|
// src/tools/orient-rituals.ts
|
|
7618
7677
|
var RULE_LISTS_EVERYONE_ONLY_LABEL = "Rules (everyone list only; run `orient mode=full` for your team and role lists):";
|
|
7619
|
-
var RULE_LISTS_UNAVAILABLE_LINE = "Rules: unavailable \u2014 rule list fetch failed, retry `orient mode=full`";
|
|
7620
|
-
function buildEveryoneOnlyRuleListsLines(ruleLists) {
|
|
7621
|
-
if (!ruleLists) return [];
|
|
7622
|
-
const everyoneOnly = {
|
|
7623
|
-
everyone: ruleLists.everyone,
|
|
7624
|
-
team: null,
|
|
7625
|
-
role: { rows: [], overCap: 0 },
|
|
7626
|
-
unassigned: ruleLists.unassigned,
|
|
7627
|
-
truncated: ruleLists.truncated,
|
|
7628
|
-
...ruleLists.namesTruncated ? { namesTruncated: true } : {}
|
|
7629
|
-
};
|
|
7630
|
-
const bucketLines = formatRuleListsLines(everyoneOnly);
|
|
7631
|
-
return [RULE_LISTS_EVERYONE_ONLY_LABEL, bucketLines.length > 0 ? bucketLines.join("\n") : "(none currently served)"];
|
|
7632
|
-
}
|
|
7633
7678
|
var SPINE_UNAVAILABLE_LINE = "Spine check: unavailable \u2014 orient fetch failed, retry `orient`";
|
|
7634
7679
|
function buildRitualsSurfaceLines(view, opts) {
|
|
7635
7680
|
const lines = [""];
|
|
@@ -7644,81 +7689,15 @@ function buildRitualsSurfaceLines(view, opts) {
|
|
|
7644
7689
|
if (view?.atCapLine) lines.push(view.atCapLine);
|
|
7645
7690
|
return lines;
|
|
7646
7691
|
}
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
function buildKeyResultLine(kr, objName) {
|
|
7657
|
-
const idPart = kr.entryId ? `${toSafeCodeSpan(sanitizeSingleLineField(kr.entryId))} ` : "";
|
|
7658
|
-
const unresolvedTag = kr.readingUnresolved ? " [reading unresolved]" : "";
|
|
7659
|
-
const values = `${krValue(kr.currentValue)} / ${krValue(kr.targetValue)} [${kr.staleness}]${unresolvedTag}`;
|
|
7660
|
-
const suffix = objName ? ` (${sanitizeSingleLineField(objName)})` : "";
|
|
7661
|
-
return `**Key result:** ${idPart}${sanitizeSingleLineField(kr.name)}${suffix}: ${values}`;
|
|
7662
|
-
}
|
|
7663
|
-
function toSafeCodeSpan(text) {
|
|
7664
|
-
const longestBacktickRun = (text.match(/`+/g) ?? []).reduce((max, run) => Math.max(max, run.length), 0);
|
|
7665
|
-
const fence = "`".repeat(longestBacktickRun + 1);
|
|
7666
|
-
const pad = text.startsWith("`") || text.endsWith("`") ? " " : "";
|
|
7667
|
-
return `${fence}${pad}${text}${pad}${fence}`;
|
|
7668
|
-
}
|
|
7669
|
-
function buildDirectionLines(view) {
|
|
7670
|
-
const purpose = view?.strategicContext?.purpose;
|
|
7671
|
-
const vision = view?.strategicContext?.vision;
|
|
7672
|
-
const productAreas = view?.strategicContext?.productAreas ?? [];
|
|
7673
|
-
const spine = view?.strategicSpine;
|
|
7674
|
-
const objectives = spine?.objectives ?? [];
|
|
7675
|
-
const orphanKeyResults = spine?.orphanKeyResults ?? [];
|
|
7676
|
-
const truncationReasons = spine?.truncationReasons ?? [];
|
|
7677
|
-
const fetchFailed = spine?.fetchFailed ?? false;
|
|
7678
|
-
const krRows = objectives.flatMap((o) => o.keyResults.map((kr) => ({ o, kr })));
|
|
7679
|
-
const strategy = (view?.strategyHighlights ?? []).filter(
|
|
7680
|
-
(e) => typeof e === "object" && e != null && typeof e.name === "string" && e.name.length > 0
|
|
7681
|
-
);
|
|
7682
|
-
const hasSomething = purpose || vision || strategy.length > 0 || productAreas.length > 0 || objectives.length > 0 || orphanKeyResults.length > 0 || truncationReasons.length > 0 || fetchFailed;
|
|
7683
|
-
if (!hasSomething) return [];
|
|
7684
|
-
const lines = ["## Strategic Context"];
|
|
7685
|
-
for (const section of spine?.order ?? DEFAULT_SPINE_ORDER) {
|
|
7686
|
-
if (section === "purpose") {
|
|
7687
|
-
if (purpose) lines.push(`**Purpose:** ${stripControlChars(purpose)}`);
|
|
7688
|
-
} else if (section === "vision") {
|
|
7689
|
-
if (vision) lines.push(`**Vision:** ${stripControlChars(vision)}`);
|
|
7690
|
-
} else if (section === "strategy") lines.push(...buildStrategyRowLines(strategy));
|
|
7691
|
-
else if (section === "product") {
|
|
7692
|
-
if (productAreas.length > 0) lines.push(`**Product areas:** ${productAreas.join(", ")}`);
|
|
7693
|
-
} else if (section === "objectives") {
|
|
7694
|
-
if (fetchFailed) lines.push("**Strategic spine:** unavailable \u2014 orient fetch failed, retry `orient`.");
|
|
7695
|
-
else if (objectives.length > 0) {
|
|
7696
|
-
for (const obj of objectives) {
|
|
7697
|
-
const idPart = obj.entryId ? `${toSafeCodeSpan(sanitizeSingleLineField(obj.entryId))} ` : "";
|
|
7698
|
-
lines.push(`**Objective:** ${idPart}${sanitizeSingleLineField(obj.name)}`);
|
|
7699
|
-
}
|
|
7700
|
-
}
|
|
7701
|
-
} else if (section === "keyResults" && !fetchFailed && (krRows.length > 0 || orphanKeyResults.length > 0 || truncationReasons.length > 0)) {
|
|
7702
|
-
for (const { o, kr } of krRows) lines.push(buildKeyResultLine(kr, o.name));
|
|
7703
|
-
if (orphanKeyResults.length > 0) {
|
|
7704
|
-
lines.push("**Key results without an objective:**");
|
|
7705
|
-
for (const kr of orphanKeyResults) lines.push(buildKeyResultLine(kr, null));
|
|
7706
|
-
}
|
|
7707
|
-
for (const reason of truncationReasons) lines.push(TRUNCATION_MESSAGES[reason]);
|
|
7708
|
-
}
|
|
7709
|
-
}
|
|
7710
|
-
return lines;
|
|
7711
|
-
}
|
|
7712
|
-
function buildStrategyRowLines(strategy) {
|
|
7713
|
-
const lines = [];
|
|
7714
|
-
for (const row of strategy) {
|
|
7715
|
-
const mark = provenanceMark(row.provenance);
|
|
7716
|
-
const rawId = row.entryId ?? row._id;
|
|
7717
|
-
const idPart = typeof rawId === "string" && rawId ? `${toSafeCodeSpan(sanitizeSingleLineField(rawId))} ` : "";
|
|
7718
|
-
const anchorSuffix = row.anchoredBy ? ` (${sanitizeSingleLineField(row.anchoredBy)})` : "";
|
|
7719
|
-
const preview = typeof row.preview === "string" && row.preview ? ` \u2014 ${stripControlChars(row.preview)}` : "";
|
|
7720
|
-
lines.push(`**Strategy:** ${mark}${idPart}${sanitizeSingleLineField(row.name)}${anchorSuffix}${preview}`);
|
|
7721
|
-
}
|
|
7692
|
+
function buildOrientBriefingLines(view, opts) {
|
|
7693
|
+
if (!view) return [];
|
|
7694
|
+
const rl = view.ruleLists ?? void 0;
|
|
7695
|
+
const ruleLists = rl && opts?.everyoneOnly ? { everyone: rl.everyone, team: null, role: { rows: [], overCap: 0 }, unassigned: rl.unassigned, truncated: rl.truncated, ...rl.namesTruncated ? { namesTruncated: true } : {} } : rl;
|
|
7696
|
+
const lines = formatBriefingLines({ facts: view.briefing ?? void 0, ruleLists, surface: "mcp" });
|
|
7697
|
+
if (!opts?.everyoneOnly || !rl) return lines;
|
|
7698
|
+
if (lines.includes("Rules:")) return lines.map((l) => l === "Rules:" ? RULE_LISTS_EVERYONE_ONLY_LABEL : l);
|
|
7699
|
+
const pull = lines.findIndex((l) => l.startsWith("Pull more:"));
|
|
7700
|
+
lines.splice(pull < 0 ? lines.length : pull, 0, RULE_LISTS_EVERYONE_ONLY_LABEL, "(none currently served)", "");
|
|
7722
7701
|
return lines;
|
|
7723
7702
|
}
|
|
7724
7703
|
async function fetchAndRenderOpenerDirection(kernelQuery2, errors, session) {
|
|
@@ -7727,7 +7706,7 @@ async function fetchAndRenderOpenerDirection(kernelQuery2, errors, session) {
|
|
|
7727
7706
|
try {
|
|
7728
7707
|
view = await kernelQuery2("chain.getOrientView", {
|
|
7729
7708
|
tier: "standard",
|
|
7730
|
-
invocationPath: "session-start",
|
|
7709
|
+
invocationPath: session?.invocationPath ?? "session-start",
|
|
7731
7710
|
// Stamps this call onto the current session/conversation/task (same as every other
|
|
7732
7711
|
// chain.getOrientView caller) so recordOrientMetric's orientCallCount/billing rollup sees it.
|
|
7733
7712
|
...session?.agentSessionId ? { sessionId: session.agentSessionId } : {},
|
|
@@ -7738,32 +7717,15 @@ async function fetchAndRenderOpenerDirection(kernelQuery2, errors, session) {
|
|
|
7738
7717
|
fetchFailed = true;
|
|
7739
7718
|
errors.push(`Direction unavailable: ${e instanceof Error ? e.message : String(e)}`);
|
|
7740
7719
|
}
|
|
7741
|
-
return [...
|
|
7720
|
+
return { lines: [...buildOrientBriefingLines(view), ...buildRitualsSurfaceLines(view, { fetchFailed: fetchFailed || view?.fetchFailed === true })], view };
|
|
7742
7721
|
}
|
|
7743
7722
|
async function buildAlreadyOrientedResult(kernelQuery2, agentSessionId, taskGroundingWarningLines2) {
|
|
7744
|
-
const
|
|
7745
|
-
|
|
7746
|
-
// conflictQueue.ts's minute-bucket convention — forces a fresh reactive result once a snooze
|
|
7747
|
-
// expires on wall-clock time alone, with no corresponding DB write to bust the cache.
|
|
7748
|
-
kernelQuery2("chain.getRitualsSurface", {
|
|
7749
|
-
now: Math.floor(Date.now() / 6e4) * 6e4
|
|
7750
|
-
}),
|
|
7751
|
-
kernelQuery2("chain.getBindingGovernanceView", {})
|
|
7752
|
-
]);
|
|
7753
|
-
const ritualsFetchFailed = ritualsSettled.status === "rejected";
|
|
7754
|
-
const rituals = ritualsSettled.status === "fulfilled" ? ritualsSettled.value : null;
|
|
7755
|
-
const ruleListsFetchFailed = bindingGovernanceSettled.status === "rejected";
|
|
7756
|
-
const ruleLists = bindingGovernanceSettled.status === "fulfilled" ? bindingGovernanceSettled.value?.ruleLists : void 0;
|
|
7757
|
-
const ritualsLines = buildRitualsSurfaceLines(rituals, { fetchFailed: ritualsFetchFailed });
|
|
7758
|
-
const ruleListsBlock = ruleListsFetchFailed ? `${RULE_LISTS_UNAVAILABLE_LINE}
|
|
7759
|
-
|
|
7760
|
-
` : ruleLists !== void 0 ? `${buildEveryoneOnlyRuleListsLines(ruleLists).join("\n")}
|
|
7761
|
-
|
|
7762
|
-
` : "";
|
|
7723
|
+
const errors = [];
|
|
7724
|
+
const { lines, view } = await fetchAndRenderOpenerDirection(kernelQuery2, errors, { agentSessionId, invocationPath: "manual-orient" });
|
|
7763
7725
|
return {
|
|
7764
7726
|
content: [{
|
|
7765
7727
|
type: "text",
|
|
7766
|
-
text: "Already oriented. Session active, writes unlocked.\n" +
|
|
7728
|
+
text: "Already oriented. Session active, writes unlocked.\n" + [...errors, ...lines].join("\n") + "\n\n" + taskGroundingWarningLines2.join("\n") + "Use `orient mode='full'` for workspace context or `orient task='...'` before substantive work."
|
|
7767
7729
|
}],
|
|
7768
7730
|
structuredContent: success(
|
|
7769
7731
|
"Already oriented. Session active, writes unlocked.",
|
|
@@ -7773,35 +7735,15 @@ async function buildAlreadyOrientedResult(kernelQuery2, agentSessionId, taskGrou
|
|
|
7773
7735
|
taskGroundingStatus: "workspace_only",
|
|
7774
7736
|
taskGroundingRequired: true,
|
|
7775
7737
|
nextStep: 'Run `orient task="describe the work"` before substantive work.',
|
|
7776
|
-
// T1's undefined-vs-null distinction: omit the key on a fetch failure, keep an explicit
|
|
7777
|
-
|
|
7778
|
-
...
|
|
7779
|
-
...
|
|
7780
|
-
...
|
|
7781
|
-
// PR #538
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
...rituals?.atCapLine !== void 0 ? { atCapLine: rituals.atCapLine } : {},
|
|
7786
|
-
// Pre-review fix 1 (TEN-3912): team/role dropped from THIS path's payload — they are
|
|
7787
|
-
// always trivial here (see the doc comment above), never this session's real rules —
|
|
7788
|
-
// and `ruleListsScope` says explicitly why, rather than shipping a shape a consumer could
|
|
7789
|
-
// misread as "this session has no team/role rules".
|
|
7790
|
-
...ruleLists ? {
|
|
7791
|
-
ruleLists: {
|
|
7792
|
-
everyone: ruleLists.everyone,
|
|
7793
|
-
unassigned: ruleLists.unassigned,
|
|
7794
|
-
truncated: ruleLists.truncated,
|
|
7795
|
-
...ruleLists.namesTruncated ? { namesTruncated: true } : {}
|
|
7796
|
-
},
|
|
7797
|
-
ruleListsScope: "everyone-only"
|
|
7798
|
-
} : {},
|
|
7799
|
-
// Round 1 review (PRRT_kwDORS4ils6mOeU8, TEN-3912): explicit `true` only on the rejection
|
|
7800
|
-
// above, mirroring the existing `fetchFailed`/`groundingStub`-style boolean flags on this
|
|
7801
|
-
// same payload (present-and-true means "this happened", omitted means "it didn't") — never
|
|
7802
|
-
// a bare `false`, never inferred from `ruleLists` being absent (a genuine no-row read also
|
|
7803
|
-
// leaves it undefined).
|
|
7804
|
-
...ruleListsFetchFailed ? { ruleListsFetchFailed: true } : {}
|
|
7738
|
+
// T1's undefined-vs-null distinction: omit the key on a fetch failure, keep an explicit null for a genuine no-row arm.
|
|
7739
|
+
...view?.directionLine !== void 0 ? { directionLine: view.directionLine } : {},
|
|
7740
|
+
...view?.verdictAskLine !== void 0 ? { verdictAskLine: view.verdictAskLine } : {},
|
|
7741
|
+
...view?.spineLine !== void 0 ? { spineLine: view.spineLine } : {},
|
|
7742
|
+
...view?.atCapLine !== void 0 ? { atCapLine: view.atCapLine } : {},
|
|
7743
|
+
// PR #538: text and structure carry the same at-cap disclosure
|
|
7744
|
+
...view?.briefing ? { briefing: view.briefing } : {},
|
|
7745
|
+
...view?.ruleLists ? { ruleLists: view.ruleLists } : {},
|
|
7746
|
+
...view ? {} : { fetchFailed: true }
|
|
7805
7747
|
}
|
|
7806
7748
|
)
|
|
7807
7749
|
};
|
|
@@ -8072,7 +8014,8 @@ async function buildOrientResponse(wsCtx, agentSessionId, errors, task) {
|
|
|
8072
8014
|
lines.push("");
|
|
8073
8015
|
const startShapeLine = formatShapeAdvisorySummaryLine(shapeAdvisorySummary);
|
|
8074
8016
|
if (startShapeLine) lines.push(startShapeLine, "");
|
|
8075
|
-
|
|
8017
|
+
const opener = await fetchAndRenderOpenerDirection(kernelQuery, errors, { agentSessionId, conversationId: getConversationId(), task });
|
|
8018
|
+
lines.push(...opener.lines);
|
|
8076
8019
|
lines.push("_Need a collection that doesn't exist yet? Creating one is not available through this tool. Ask a platform admin to provision it, or enable the module ontology pack that owns it._");
|
|
8077
8020
|
lines.push("");
|
|
8078
8021
|
let activeBets = [];
|
|
@@ -8082,11 +8025,10 @@ async function buildOrientResponse(wsCtx, agentSessionId, errors, task) {
|
|
|
8082
8025
|
} catch {
|
|
8083
8026
|
}
|
|
8084
8027
|
let governanceEntries = { principles: [], standards: [], businessRules: [] };
|
|
8085
|
-
|
|
8028
|
+
const ruleListsView = opener.view?.ruleLists ?? void 0;
|
|
8086
8029
|
let bindingGovernanceView;
|
|
8087
8030
|
try {
|
|
8088
8031
|
bindingGovernanceView = await kernelQuery("chain.getBindingGovernanceView", { task });
|
|
8089
|
-
ruleListsView = bindingGovernanceView?.ruleLists;
|
|
8090
8032
|
} catch {
|
|
8091
8033
|
}
|
|
8092
8034
|
if (task) {
|
|
@@ -8120,8 +8062,6 @@ async function buildOrientResponse(wsCtx, agentSessionId, errors, task) {
|
|
|
8120
8062
|
lines.push("");
|
|
8121
8063
|
}
|
|
8122
8064
|
lines.push(...buildOperatingProtocol(governanceEntries, task));
|
|
8123
|
-
const ruleLines = formatRuleListsLines(ruleListsView);
|
|
8124
|
-
if (ruleLines.length > 0) lines.push("", "Rules:", ...ruleLines);
|
|
8125
8065
|
if (coherence) {
|
|
8126
8066
|
lines.push(...coherence.lines);
|
|
8127
8067
|
}
|
|
@@ -8169,8 +8109,6 @@ async function buildOrientResponse(wsCtx, agentSessionId, errors, task) {
|
|
|
8169
8109
|
lines.push(
|
|
8170
8110
|
...buildOperatingProtocol({ truncated: bindingGovernanceView?._budget?.truncated === true })
|
|
8171
8111
|
);
|
|
8172
|
-
const noTaskRuleLines = formatRuleListsLines(ruleListsView);
|
|
8173
|
-
if (noTaskRuleLines.length > 0) lines.push("", "Rules:", ...noTaskRuleLines);
|
|
8174
8112
|
if (coherence) {
|
|
8175
8113
|
lines.push(...coherence.lines);
|
|
8176
8114
|
}
|
|
@@ -8487,8 +8425,7 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
|
|
|
8487
8425
|
"Full onboarding is optional: call `orient action=start` if you want guided workspace setup. If you already ran setup, continue your task without restarting it."
|
|
8488
8426
|
];
|
|
8489
8427
|
scanLines.push(...buildRitualsSurfaceLines(orientView, { fetchFailed: orientFetchFailed || orientView?.fetchFailed === true }));
|
|
8490
|
-
|
|
8491
|
-
if (blankRuleLines.length > 0) scanLines.push("", "Rules:", ...blankRuleLines);
|
|
8428
|
+
scanLines.push("", ...buildOrientBriefingLines(orientView));
|
|
8492
8429
|
let oriented = false;
|
|
8493
8430
|
let orientationStatus2 = "no_session";
|
|
8494
8431
|
if (agentSessionId && taskAsked) {
|
|
@@ -8525,7 +8462,7 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
|
|
|
8525
8462
|
lines.push("");
|
|
8526
8463
|
}
|
|
8527
8464
|
if (mode === "brief") {
|
|
8528
|
-
lines.push(...
|
|
8465
|
+
lines.push(...buildOrientBriefingLines(orientView));
|
|
8529
8466
|
if (orientView?.strategicContext) {
|
|
8530
8467
|
const sc = orientView.strategicContext;
|
|
8531
8468
|
if (sc.playingFieldCount != null && sc.playingFieldCount > 0) {
|
|
@@ -8613,8 +8550,6 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
|
|
|
8613
8550
|
} else {
|
|
8614
8551
|
lines.push(...buildOperatingProtocol());
|
|
8615
8552
|
}
|
|
8616
|
-
const ruleLines = formatRuleListsLines(orientView.ruleLists);
|
|
8617
|
-
if (ruleLines.length > 0) lines.push("", "Rules:", ...ruleLines);
|
|
8618
8553
|
}
|
|
8619
8554
|
let orientationStatus2 = "no_session";
|
|
8620
8555
|
if (agentSessionId && taskAsked) {
|
|
@@ -8696,6 +8631,7 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
|
|
|
8696
8631
|
}
|
|
8697
8632
|
lines.push("_Need a collection that doesn't exist yet? Creating one is not available through this tool. Ask a platform admin to provision it, or enable the module ontology pack that owns it._");
|
|
8698
8633
|
lines.push("");
|
|
8634
|
+
lines.push(...buildOrientBriefingLines(orientView), "");
|
|
8699
8635
|
let fullCoherenceSnapshot;
|
|
8700
8636
|
if (readiness) {
|
|
8701
8637
|
if (!sampleTruncated && readiness.gaps.length > 0) {
|
|
@@ -8720,16 +8656,10 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
|
|
|
8720
8656
|
if (task) {
|
|
8721
8657
|
lines.push(`Working on: **${task}**`);
|
|
8722
8658
|
lines.push("");
|
|
8723
|
-
lines.push(...buildDirectionLines(orientView));
|
|
8724
8659
|
if (orientView?.strategicContext) {
|
|
8725
8660
|
const sc = orientView.strategicContext;
|
|
8726
8661
|
if (sc.playingFieldCount != null && sc.playingFieldCount > 0) lines.push(`**Playing field (${sc.playingFieldCount}):** ${(sc.playingField ?? []).join(", ")}`);
|
|
8727
|
-
|
|
8728
|
-
const wpSingularFull = getCollectionLabel("work_package", "singular", vocabCtx);
|
|
8729
|
-
const wpPluralFull = getCollectionLabel("work_package", "plural", vocabCtx);
|
|
8730
|
-
const betLine = currentWP ? `**Current ${wpSingularFull}:** ${currentWP}. ${sc.activeWorkPackageCount} active ${wpPluralFull}.` : `No active ${wpPluralFull}.`;
|
|
8731
|
-
lines.push(`${betLine} ${sc.activeTensionCount} open tension(s).`);
|
|
8732
|
-
lines.push("");
|
|
8662
|
+
lines.push(`${sc.activeWorkPackageCount} active ${getCollectionLabel("work_package", "plural", vocabCtx)}, ${sc.activeTensionCount} open tension(s).`, "");
|
|
8733
8663
|
}
|
|
8734
8664
|
if (orientView?.continuingFrom && orientView.continuingFrom.length > 0) {
|
|
8735
8665
|
lines.push("## Continuing from");
|
|
@@ -8918,8 +8848,6 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
|
|
|
8918
8848
|
lines.push(...formatRecoveryBlock(recoveryBlock));
|
|
8919
8849
|
}
|
|
8920
8850
|
} else {
|
|
8921
|
-
const scNoTaskLines = buildDirectionLines(orientView);
|
|
8922
|
-
if (scNoTaskLines.length > 0) lines.push(...scNoTaskLines, "");
|
|
8923
8851
|
lines.push(...buildRitualsSurfaceLines(orientView, { fetchFailed: orientFetchFailed || orientView?.fetchFailed === true }));
|
|
8924
8852
|
if (orientView?.activeWorkPackages?.length) {
|
|
8925
8853
|
lines.push("## Active work packages \u2014 current scope");
|
|
@@ -8974,8 +8902,6 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
|
|
|
8974
8902
|
lines.push("");
|
|
8975
8903
|
}
|
|
8976
8904
|
}
|
|
8977
|
-
const ruleLinesFull = formatRuleListsLines(orientView?.ruleLists);
|
|
8978
|
-
if (ruleLinesFull.length > 0) lines.push("", "Rules:", ...ruleLinesFull);
|
|
8979
8905
|
const classificationGaps = readiness?.gaps?.filter((g) => g.id?.startsWith?.(PURPOSE_GAP_PREFIX)) ?? [];
|
|
8980
8906
|
if (classificationGaps.length > 0) {
|
|
8981
8907
|
lines.push("## Classification gaps");
|
|
@@ -12040,12 +11966,19 @@ async function handleStart2(data) {
|
|
|
12040
11966
|
lines.push(`Acting as role: ${result2.roleName ?? result2.roleEntryId}.`);
|
|
12041
11967
|
}
|
|
12042
11968
|
lines.push(FEEDBACK_SUBMIT_HINT);
|
|
12043
|
-
const
|
|
12044
|
-
|
|
12045
|
-
|
|
12046
|
-
}
|
|
12047
|
-
|
|
12048
|
-
|
|
11969
|
+
const questionNotice = result2.notices?.find((n) => n.source === QUESTION_ACK_GATE_SOURCE_ID);
|
|
11970
|
+
const noticeLines = formatNoticeLines(result2.notices?.filter((n) => n !== questionNotice));
|
|
11971
|
+
if (noticeLines.length > 0) lines.push("", "Notices:", ...noticeLines);
|
|
11972
|
+
const openQuestions = (questionNotice?.payload?.questions ?? []).map((q) => ({ entryId: q.sourcePointer, title: q.name, ageDays: q.ageDays }));
|
|
11973
|
+
lines.push("", ...formatBriefingLines({
|
|
11974
|
+
workspaceName: result2.workspaceName,
|
|
11975
|
+
actingRole: result2.roleName,
|
|
11976
|
+
facts: result2.briefing,
|
|
11977
|
+
ruleLists: result2.ruleLists,
|
|
11978
|
+
openQuestions,
|
|
11979
|
+
openQuestionsTruncated: questionNotice?.payload?.truncated === true,
|
|
11980
|
+
surface: "mcp"
|
|
11981
|
+
}));
|
|
12049
11982
|
const summary = `Session ${result2.sessionId} active. Workspace ${result2.workspaceName}. Orient with a task first; workflow checkpoints and organisation-structure writes still require it.`;
|
|
12050
11983
|
return {
|
|
12051
11984
|
content: [{ type: "text", text: lines.join("\n") }],
|
|
@@ -12059,8 +11992,10 @@ async function handleStart2(data) {
|
|
|
12059
11992
|
feedbackQueueNew: result2.feedbackQueueNew,
|
|
12060
11993
|
feedbackOldestNewAt: result2.feedbackOldestNewAt,
|
|
12061
11994
|
notices: result2.notices ?? [],
|
|
12062
|
-
ruleLists: result2.ruleLists
|
|
11995
|
+
ruleLists: result2.ruleLists,
|
|
12063
11996
|
// TASK-436
|
|
11997
|
+
briefing: result2.briefing
|
|
11998
|
+
// TASK-552
|
|
12064
11999
|
// Finding #16: bare `parameters: {}` lets orient's schema default kick in
|
|
12065
12000
|
// (action defaults to "task", which requires a `task` string) — the suggested
|
|
12066
12001
|
// next-action call failed validation instead of running. `action: "start"` is
|
|
@@ -13783,16 +13718,11 @@ Write via \`update\`: \`draft\` | \`archived\` (\`accepted\` via \`commit\`, nev
|
|
|
13783
13718
|
`;
|
|
13784
13719
|
|
|
13785
13720
|
// src/resources/orientationMarkdown.ts
|
|
13786
|
-
function buildOrientationMarkdown(collections, standards, businessRules, principles, directionLines
|
|
13721
|
+
function buildOrientationMarkdown(collections, standards, businessRules, principles, directionLines) {
|
|
13787
13722
|
const sections = ["# Product Brain \u2014 Orientation"];
|
|
13788
13723
|
if (directionLines && directionLines.length > 0) {
|
|
13789
13724
|
sections.push(directionLines.join("\n"));
|
|
13790
13725
|
}
|
|
13791
|
-
if (ruleLines && ruleLines.length > 0) {
|
|
13792
|
-
sections.push(
|
|
13793
|
-
"## Rules (delivered lists)\nEveryone/team/role rules currently served to this workspace and role (DEC-1774) \u2014 distinct from the collection-listing section below.\n\n" + ruleLines.join("\n")
|
|
13794
|
-
);
|
|
13795
|
-
}
|
|
13796
13726
|
sections.push(
|
|
13797
13727
|
"## About Product Brain (PB)\nPB is a knowledge management system used by many product teams. This section describes how PB works \u2014 not your product.\n\n### How PB Organizes Its Tools\n- **Tools** = actions with side-effects or dynamic computation (capture, accept, search).\n- **Resources** = stable, read-only data (orientation, terminology, collection schemas).\n- **Prompts** = multi-step choreography (workflows, guided capture, deep dives).\n- Every tool, resource, and prompt works for ANY workspace \u2014 no bespoke logic.\n- Resource templates (URI params) serve workspace-specific data through generic patterns.\n- Compound tools with `action` enums keep the tool count minimal.\n\n" + DATA_HANDLING_SECTION
|
|
13798
13728
|
);
|
|
@@ -13807,7 +13737,7 @@ function buildOrientationMarkdown(collections, standards, businessRules, princip
|
|
|
13807
13737
|
wsRules.push({ id: r.entryId ?? "", name: r.name, severity: r.data?.severity ?? void 0, source: "rules" });
|
|
13808
13738
|
}
|
|
13809
13739
|
if (wsRules.length > 0) {
|
|
13810
|
-
const
|
|
13740
|
+
const ruleLines = wsRules.map((r) => {
|
|
13811
13741
|
const sev = r.severity ? ` [${r.severity}]` : "";
|
|
13812
13742
|
return `- **${r.id}**: ${r.name}${sev}`;
|
|
13813
13743
|
}).join("\n");
|
|
@@ -13815,7 +13745,7 @@ function buildOrientationMarkdown(collections, standards, businessRules, princip
|
|
|
13815
13745
|
`## Your Workspace Principles & Rules (${wsRules.length} active)
|
|
13816
13746
|
These are principles, standards, and rules your team has accepted onto the Chain. Respect them during implementation.
|
|
13817
13747
|
|
|
13818
|
-
` +
|
|
13748
|
+
` + ruleLines + '\n\nUse `entries action=get entryId="<ID>"` to drill into any rule before making changes in that area.'
|
|
13819
13749
|
);
|
|
13820
13750
|
} else {
|
|
13821
13751
|
sections.push(
|
|
@@ -13900,7 +13830,6 @@ async function buildOrientationResourceText(kernelQuery2, agentSessionId) {
|
|
|
13900
13830
|
const businessRules = rulesResult.status === "fulfilled" ? rulesResult.value : null;
|
|
13901
13831
|
const principles = principlesResult.status === "fulfilled" ? principlesResult.value : null;
|
|
13902
13832
|
let directionLines;
|
|
13903
|
-
let ruleLines = [];
|
|
13904
13833
|
if (orientViewResult.status === "rejected") {
|
|
13905
13834
|
const reason = orientViewResult.reason instanceof Error ? orientViewResult.reason.message : String(orientViewResult.reason);
|
|
13906
13835
|
const normalized = sanitizeSingleLineField(reason);
|
|
@@ -13908,10 +13837,9 @@ async function buildOrientationResourceText(kernelQuery2, agentSessionId) {
|
|
|
13908
13837
|
directionLines = [`_Strategic context unavailable: the spine read failed (${truncated})_`];
|
|
13909
13838
|
} else {
|
|
13910
13839
|
const orientView = orientViewResult.value;
|
|
13911
|
-
directionLines =
|
|
13912
|
-
ruleLines = agentSessionId ? formatRuleListsLines(orientView.ruleLists) : buildEveryoneOnlyRuleListsLines(orientView.ruleLists);
|
|
13840
|
+
directionLines = buildOrientBriefingLines(orientView, { everyoneOnly: !agentSessionId });
|
|
13913
13841
|
}
|
|
13914
|
-
return buildOrientationMarkdown(collections, standards, businessRules, principles, directionLines
|
|
13842
|
+
return buildOrientationMarkdown(collections, standards, businessRules, principles, directionLines);
|
|
13915
13843
|
}
|
|
13916
13844
|
|
|
13917
13845
|
// src/resources/terminologyResource.ts
|
|
@@ -14540,4 +14468,4 @@ export {
|
|
|
14540
14468
|
createProductBrainServer,
|
|
14541
14469
|
initFeatureFlags
|
|
14542
14470
|
};
|
|
14543
|
-
//# sourceMappingURL=chunk-
|
|
14471
|
+
//# sourceMappingURL=chunk-JSKIMDXR.js.map
|