@productbrain/mcp 0.0.1-beta.33 → 0.0.1-beta.35
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.
|
@@ -2316,23 +2316,40 @@ var SHAPE_WORKFLOW = {
|
|
|
2316
2316
|
name: "Shape a Bet",
|
|
2317
2317
|
shortDescription: "Coached shaping session \u2014 problem \u2192 appetite \u2192 elements \u2192 architecture \u2192 de-risk \u2192 pitch. Uses the `facilitate` tool for scoring and Chain capture.",
|
|
2318
2318
|
icon: "\u25C6",
|
|
2319
|
-
facilitatorPreamble: `You are now in **Shaping Mode**. You are
|
|
2319
|
+
facilitatorPreamble: `You are now in **Shaping Mode**. You are an **investigating** shaping facilitator powered by the \`facilitate\` tool and Cursor sub-agents.
|
|
2320
2320
|
|
|
2321
2321
|
## Your Behavior
|
|
2322
2322
|
|
|
2323
|
-
1. **Start with \`facilitate action=start\`.** This creates a draft bet on the Chain and returns the Studio URL
|
|
2324
|
-
2. **
|
|
2325
|
-
3. **
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2323
|
+
1. **Start with \`facilitate action=start\`.** This creates a draft bet on the Chain and returns the Studio URL, initial coaching, and an investigationBrief.
|
|
2324
|
+
2. **Investigate before asking.** At each phase transition, read the \`investigationBrief\` in the structured response. Spawn sub-agents to search the codebase and Chain. Synthesize findings into proposals. Present proposals for user reaction.
|
|
2325
|
+
3. **Use \`facilitate action=respond\` for every input.** Pass the user's text, betEntryId, dimension, and the \`source\` field:
|
|
2326
|
+
- \`source="user"\` \u2014 user typed this directly (default, full score weight)
|
|
2327
|
+
- \`source="agent_proposal"\` \u2014 you generated this proposal text (discounted score)
|
|
2328
|
+
- \`source="user_reaction"\` \u2014 user reacting to your proposal (full score weight)
|
|
2329
|
+
4. **Read the structured response carefully.** The coaching object tells you what to say next. The scorecard tells you what's missing. The investigationBrief tells you what to investigate for the next phase.
|
|
2330
|
+
5. **One dimension at a time.** Follow the round progression below. Don't dump all dimensions at once.
|
|
2331
|
+
6. **Push back with evidence.** Don't just ask "Who's affected?" \u2014 search the codebase for evidence and say "I found 3 workarounds in the codebase related to this. Here's what they suggest about the problem."
|
|
2329
2332
|
7. **Capture elements and risks inline** using the \`capture\` parameter on respond calls. Each becomes a Chain entry with a relation to the bet.
|
|
2330
|
-
8. **
|
|
2333
|
+
8. **CRITICAL: Elements, rabbit holes, and no-gos MUST use the \`capture\` parameter.** Never pass them as plain \`userInput\` without \`capture\`. Without \`capture\`, nothing is saved to the bet \u2014 the data is silently lost. Always include \`capture={type:"element"|"risk"|"noGo", name:"...", description:"..."}\` for every structured item. Each element, risk, and no-go needs its own \`respond\` call with \`capture\`.
|
|
2334
|
+
9. **When captureReady is true, offer to finalize** \u2014 but don't force it. The user decides when the shape is complete.
|
|
2335
|
+
|
|
2336
|
+
## Investigation Pattern (ENT-59)
|
|
2337
|
+
|
|
2338
|
+
At phase transitions, follow this pattern:
|
|
2339
|
+
1. Read the \`investigationBrief\` from the structured response
|
|
2340
|
+
2. Spawn sub-agents in parallel (max 2, 30s budget each):
|
|
2341
|
+
- \`explore\` sub-agent: codebase searches (files, patterns, architecture)
|
|
2342
|
+
- \`generalPurpose\` sub-agent: Chain searches (entries, governance, context)
|
|
2343
|
+
3. Synthesize findings into a concrete proposal (cite files and entry IDs)
|
|
2344
|
+
4. Present the proposal for user reaction \u2014 "Based on the codebase, I'd suggest..."
|
|
2345
|
+
5. Score the user's reaction with \`source="user_reaction"\` (full weight)
|
|
2346
|
+
|
|
2347
|
+
If investigation fails or times out, continue with the conversation \u2014 the user's knowledge is always the primary input.
|
|
2331
2348
|
|
|
2332
2349
|
## DEC-56 Boundary
|
|
2333
2350
|
|
|
2334
|
-
The **server judges** \u2014 it scores input against 6 rubric dimensions, detects overlap, checks governance alignment.
|
|
2335
|
-
**You coach** \u2014 you interpret the structured response, synthesize naturally,
|
|
2351
|
+
The **server judges** \u2014 it scores input against 6 rubric dimensions, detects overlap, checks governance alignment. Agent-generated text is scored at ${0.6}x weight to prevent keyword inflation (RH1).
|
|
2352
|
+
**You coach** \u2014 you interpret the structured response, synthesize naturally, investigate proactively, propose grounded solutions, and push back when shaping isn't sharp.
|
|
2336
2353
|
The \`coaching.suggestedQuestion\` is a suggestion, not a script \u2014 rephrase or skip based on conversation flow.
|
|
2337
2354
|
|
|
2338
2355
|
## Error Recovery
|
|
@@ -2349,7 +2366,8 @@ If any facilitate call fails:
|
|
|
2349
2366
|
- Keep chat messages to 5 lines or fewer \u2014 heavy context degrades performance
|
|
2350
2367
|
- Use AskQuestion for structured choices (appetite, gates)
|
|
2351
2368
|
- Synthesize between phases \u2014 reflect what was decided before moving on
|
|
2352
|
-
-
|
|
2369
|
+
- When proposing, cite evidence: "I found X in the codebase" or "The Chain has DEC-Y about this"
|
|
2370
|
+
- If the user seems stuck, investigate and propose rather than just asking`,
|
|
2353
2371
|
rounds: [
|
|
2354
2372
|
{
|
|
2355
2373
|
id: "context",
|
|
@@ -2357,7 +2375,7 @@ If any facilitate call fails:
|
|
|
2357
2375
|
label: "Gather Context",
|
|
2358
2376
|
type: "open",
|
|
2359
2377
|
instruction: "Before shaping, let's see what the Chain already knows. Search for related entries, business rules, and existing decisions.",
|
|
2360
|
-
facilitatorGuidance: "
|
|
2378
|
+
facilitatorGuidance: "**Investigate proactively.** Spawn sub-agents in parallel: (1) `explore` agent to search the codebase for code related to the bet topic \u2014 find modules, patterns, and pain points. (2) `generalPurpose` agent to search the Chain: call `orient`, use `entries action=search` with keywords, surface related tensions, active bets, and applicable business rules. Synthesize both into a 3-5 line context brief: what the codebase reveals, what the Chain knows, what governance applies. Present with IDs and file paths. Then transition: 'Here's what I found. Does this match the problem you're seeing?'",
|
|
2361
2379
|
outputSchema: {
|
|
2362
2380
|
field: "context",
|
|
2363
2381
|
description: "Chain context: related entries, governance, existing decisions",
|
|
@@ -2371,7 +2389,7 @@ If any facilitate call fails:
|
|
|
2371
2389
|
label: "Frame the Problem",
|
|
2372
2390
|
type: "open",
|
|
2373
2391
|
instruction: "What's the problem? Who's affected? What's the workaround today? How much time is this worth?",
|
|
2374
|
-
facilitatorGuidance: "This round covers problem_clarity AND appetite. Call `facilitate action=respond` with dimension='problem_clarity' for the problem input, then dimension='appetite' for the time budget. Push
|
|
2392
|
+
facilitatorGuidance: "This round covers problem_clarity AND appetite. If the investigationBrief has framing tasks, search the codebase for workarounds, TODOs, and hacks related to the problem \u2014 cite what you find as evidence. Call `facilitate action=respond` with dimension='problem_clarity' for the problem input, then dimension='appetite' for the time budget. Push with evidence: 'I found 3 workaround patterns in the codebase \u2014 this suggests the problem is bigger than it looks.' Use AskQuestion for appetite: Small Batch (1-2 weeks) or Big Batch (6 weeks). When both dimensions score 6+, present the frame and ask for Frame Go confirmation. If new terms surfaced, capture them to the glossary via `capture`. If tensions surfaced, capture them too.",
|
|
2375
2393
|
questions: [
|
|
2376
2394
|
{
|
|
2377
2395
|
id: "appetite",
|
|
@@ -2404,7 +2422,7 @@ If any facilitate call fails:
|
|
|
2404
2422
|
label: "Find the Elements",
|
|
2405
2423
|
type: "open",
|
|
2406
2424
|
instruction: "What are the solution elements? Think breadboard level \u2014 places, affordances, connections. What's the architecture?",
|
|
2407
|
-
facilitatorGuidance: "
|
|
2425
|
+
facilitatorGuidance: "**Investigate first.** Read the investigationBrief. Spawn sub-agents to search the codebase for affected modules, existing architecture patterns, and API boundaries. Synthesize findings into 3-5 proposed solution elements at breadboard level, citing specific files and modules. Present proposals for user reaction: 'Based on the codebase, here are the elements I'd suggest.' For each confirmed element, capture with its own respond call: `facilitate action=respond betEntryId='...' dimension='elements' source='user_reaction' userInput='...' capture={type:'element', name:'Element Name', description:'What it does'}`. Without the `capture` parameter, the element is NOT saved to the bet \u2014 you will get a WARNING if you forget. Each captured element becomes a features entry linked to the bet via part_of. For Big Batch: also investigate architecture \u2014 search for layer boundaries and dependency directions, then propose architecture. Call respond with dimension='architecture' for architecture input (no capture needed \u2014 free-form text). Check business rules: do any elements conflict with governance surfaced in Round 1? Capture new glossary terms and decisions as they surface. Aim for 3-5 elements. When elements score 6+ (and architecture for Big Batch), present for confirmation.",
|
|
2408
2426
|
outputSchema: {
|
|
2409
2427
|
field: "elements",
|
|
2410
2428
|
description: "Core solution elements and architecture",
|
|
@@ -2419,7 +2437,7 @@ If any facilitate call fails:
|
|
|
2419
2437
|
label: "De-risk \u2014 Rabbit Holes & No-Gos",
|
|
2420
2438
|
type: "open",
|
|
2421
2439
|
instruction: "What could go wrong? What are we NOT building? Walk through the solution slowly and find the risks.",
|
|
2422
|
-
facilitatorGuidance: "
|
|
2440
|
+
facilitatorGuidance: "**Investigate first.** Read the investigationBrief. Spawn sub-agents to search the codebase for fragile code, tight coupling, missing tests, performance-sensitive paths, and external dependencies near the affected modules. Propose risks with evidence: 'I found that X module has no tests and is tightly coupled to Y \u2014 this is a rabbit hole.' Every confirmed risk MUST be captured with its own respond call: `facilitate action=respond betEntryId='...' dimension='risks' source='user_reaction' userInput='...' capture={type:'risk', name:'Risk Name', description:'What could go wrong', theme:'implementation'}`. Each becomes a tensions entry linked to the bet via constrains. Push for mitigations \u2014 every risk needs a patch or explicit acceptance. Then declare no-gos: 'Based on what I've seen, I'd suggest these no-gos.' Every no-go MUST use capture: `facilitate action=respond betEntryId='...' dimension='boundaries' source='user_reaction' userInput='...' capture={type:'noGo', name:'No-Go Title', description:'Why we are not doing this'}`. Without the `capture` parameter on each call, the item is NOT saved \u2014 you will get a WARNING. When risks score 6+ and boundaries score 4+, present Shape Go gate: 'Is this buildable within the appetite?'",
|
|
2423
2441
|
questions: [
|
|
2424
2442
|
{
|
|
2425
2443
|
id: "shape-go",
|
|
@@ -2676,6 +2694,7 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
|
|
|
2676
2694
|
import { z as z12 } from "zod";
|
|
2677
2695
|
|
|
2678
2696
|
// src/tools/facilitate-rubrics.ts
|
|
2697
|
+
var AGENT_DISCOUNT_FACTOR = 0.6;
|
|
2679
2698
|
var DIMENSIONS = [
|
|
2680
2699
|
"problem_clarity",
|
|
2681
2700
|
"appetite",
|
|
@@ -3118,12 +3137,19 @@ var SCORERS = {
|
|
|
3118
3137
|
boundaries: scoreBoundaries
|
|
3119
3138
|
};
|
|
3120
3139
|
function scoreDimension(dimension, ctx) {
|
|
3121
|
-
|
|
3140
|
+
const raw = SCORERS[dimension](ctx);
|
|
3141
|
+
if (ctx.source === "agent_proposal") {
|
|
3142
|
+
return {
|
|
3143
|
+
...raw,
|
|
3144
|
+
score: clamp(Math.round(raw.score * AGENT_DISCOUNT_FACTOR), 0, 10)
|
|
3145
|
+
};
|
|
3146
|
+
}
|
|
3147
|
+
return raw;
|
|
3122
3148
|
}
|
|
3123
3149
|
function scoreAll(ctx) {
|
|
3124
3150
|
const results = {};
|
|
3125
3151
|
for (const dim of DIMENSIONS) {
|
|
3126
|
-
results[dim] =
|
|
3152
|
+
results[dim] = scoreDimension(dim, ctx);
|
|
3127
3153
|
}
|
|
3128
3154
|
return results;
|
|
3129
3155
|
}
|
|
@@ -3212,6 +3238,57 @@ function extractPhrase(text, maxLen) {
|
|
|
3212
3238
|
function capitalize(s) {
|
|
3213
3239
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
3214
3240
|
}
|
|
3241
|
+
var PHASE_INVESTIGATIONS = {
|
|
3242
|
+
context: (betName) => ({
|
|
3243
|
+
phase: "context",
|
|
3244
|
+
dimension: "problem_clarity",
|
|
3245
|
+
tasks: [
|
|
3246
|
+
{ target: "chain", query: `Search for entries related to: ${betName}`, purpose: "Find existing tensions, decisions, and bets that overlap" },
|
|
3247
|
+
{ target: "chain", query: "List active governance: principles, standards, business-rules", purpose: "Surface constraints the solution must honor" },
|
|
3248
|
+
{ target: "codebase", query: `Search for code related to: ${betName}`, purpose: "Understand current implementation and pain points" }
|
|
3249
|
+
],
|
|
3250
|
+
proposalGuidance: "Synthesize findings into a 3-5 line context brief: what the Chain knows, what the codebase reveals, what governance applies.",
|
|
3251
|
+
reactionPrompt: "Here's what I found. Does this match what you're seeing, or is the problem different from what the Chain suggests?"
|
|
3252
|
+
}),
|
|
3253
|
+
framing: (betName) => ({
|
|
3254
|
+
phase: "framing",
|
|
3255
|
+
dimension: "problem_clarity",
|
|
3256
|
+
tasks: [
|
|
3257
|
+
{ target: "codebase", query: `Find workarounds, TODOs, or hacks related to: ${betName}`, purpose: "Surface concrete evidence of the problem" },
|
|
3258
|
+
{ target: "chain", query: "Search for related tensions and user complaints", purpose: "Quantify how often this problem occurs" }
|
|
3259
|
+
],
|
|
3260
|
+
proposalGuidance: "Propose a problem statement based on codebase evidence. Include who's affected and what the workaround looks like in the code.",
|
|
3261
|
+
reactionPrompt: "Based on the codebase, here's a draft problem statement. Does this capture it, or is the real problem different?"
|
|
3262
|
+
}),
|
|
3263
|
+
elements: (betName) => ({
|
|
3264
|
+
phase: "elements",
|
|
3265
|
+
dimension: "elements",
|
|
3266
|
+
tasks: [
|
|
3267
|
+
{ target: "codebase", query: `Find modules, services, and components that would be affected by: ${betName}`, purpose: "Map the solution to existing architecture" },
|
|
3268
|
+
{ target: "architecture", query: "Identify layer boundaries, API contracts, and dependency directions", purpose: "Ground elements in real architecture" },
|
|
3269
|
+
{ target: "chain", query: "Check DEC-31, STA-3, and other architecture standards", purpose: "Ensure elements respect existing decisions" }
|
|
3270
|
+
],
|
|
3271
|
+
proposalGuidance: "Propose 3-5 solution elements at breadboard level. Each element should name the layer it lives in, what it does, and how it connects to existing code.",
|
|
3272
|
+
reactionPrompt: "I've mapped out these solution elements based on the codebase. Which feel right? Which need adjustment?"
|
|
3273
|
+
}),
|
|
3274
|
+
derisking: (betName) => ({
|
|
3275
|
+
phase: "derisking",
|
|
3276
|
+
dimension: "risks",
|
|
3277
|
+
tasks: [
|
|
3278
|
+
{ target: "codebase", query: `Find fragile code, tight coupling, or missing tests near: ${betName}`, purpose: "Surface technical risks from code" },
|
|
3279
|
+
{ target: "codebase", query: "Check for performance-sensitive paths, database queries, and external dependencies", purpose: "Identify performance and reliability risks" },
|
|
3280
|
+
{ target: "chain", query: "Search for related tensions and past decisions that constrain this solution", purpose: "Surface risks from existing constraints" }
|
|
3281
|
+
],
|
|
3282
|
+
proposalGuidance: "Propose rabbit holes with severity and mitigations. Each risk should cite specific code or Chain evidence. Also propose no-gos \u2014 what should be explicitly excluded.",
|
|
3283
|
+
reactionPrompt: "These are the risks I found in the codebase. Are these real concerns? What am I missing?"
|
|
3284
|
+
}),
|
|
3285
|
+
validation: () => null,
|
|
3286
|
+
capture: () => null
|
|
3287
|
+
};
|
|
3288
|
+
function buildInvestigationBrief(phase, betName, betEntryId) {
|
|
3289
|
+
const builder = PHASE_INVESTIGATIONS[phase];
|
|
3290
|
+
return builder(betName, betEntryId);
|
|
3291
|
+
}
|
|
3215
3292
|
function generateBuildContract(ctx) {
|
|
3216
3293
|
const lines = ["## Build Contract"];
|
|
3217
3294
|
const consult = [
|
|
@@ -3283,6 +3360,7 @@ var facilitateSchema = z12.object({
|
|
|
3283
3360
|
userInput: z12.string().optional().describe("User's input text for respond action."),
|
|
3284
3361
|
dimension: z12.string().optional().describe("Explicit dimension to score against (e.g. 'problem_clarity'). If omitted, inferred from scorecard."),
|
|
3285
3362
|
betName: z12.string().optional().describe("Name for the bet (used in start action)."),
|
|
3363
|
+
source: z12.enum(["user", "agent_proposal", "user_reaction"]).default("user").optional().describe("ENT-59: Source of the input text. 'user' = typed by user (default, full score weight). 'agent_proposal' = agent-generated proposal (discounted score). 'user_reaction' = user reacting to agent proposal (full weight)."),
|
|
3286
3364
|
capture: z12.object({
|
|
3287
3365
|
type: z12.enum(["element", "risk", "noGo", "decision"]).describe("What to capture"),
|
|
3288
3366
|
name: z12.string().describe("Entry name"),
|
|
@@ -3359,8 +3437,11 @@ function buildDirective(scorecard, phase, betEntryId, captureReady, activeDimens
|
|
|
3359
3437
|
`1. **Go** \u2014 move to solution elements`,
|
|
3360
3438
|
`2. **Refine** \u2014 something's not right, let's adjust`,
|
|
3361
3439
|
``,
|
|
3362
|
-
`If Go:
|
|
3363
|
-
`
|
|
3440
|
+
`If Go: **investigate first** \u2014 use the investigationBrief in the structured response to search the codebase and Chain.`,
|
|
3441
|
+
`Spawn sub-agents to explore the codebase for affected modules, existing architecture, and related patterns.`,
|
|
3442
|
+
`Then propose 3-5 solution elements grounded in what you found.`,
|
|
3443
|
+
`Present proposals for user reaction: "Based on the codebase, here are the elements I'd suggest. Which feel right?"`,
|
|
3444
|
+
`For each confirmed element, call \`facilitate action=respond betEntryId="${b}" dimension="elements" source="user_reaction"\` with the user's reaction.`,
|
|
3364
3445
|
`If Refine: ask what needs adjusting, then call respond with dimension="problem_clarity" or "appetite".`
|
|
3365
3446
|
].join("\n");
|
|
3366
3447
|
}
|
|
@@ -3392,6 +3473,17 @@ function buildDirective(scorecard, phase, betEntryId, captureReady, activeDimens
|
|
|
3392
3473
|
}
|
|
3393
3474
|
if (nextDimension && nextDimension !== activeDimension) {
|
|
3394
3475
|
const nextLabel = DIMENSION_LABELS[nextDimension];
|
|
3476
|
+
const investigationPhases = ["elements", "architecture", "risks", "boundaries"];
|
|
3477
|
+
const shouldInvestigate = investigationPhases.includes(nextDimension);
|
|
3478
|
+
if (shouldInvestigate) {
|
|
3479
|
+
return [
|
|
3480
|
+
`Briefly synthesize what was just covered (2 lines max), then move to **${nextLabel}**.`,
|
|
3481
|
+
`**Investigate first:** Use the investigationBrief to search the codebase and Chain before asking the user.`,
|
|
3482
|
+
`Spawn sub-agents to gather evidence, then propose findings for user reaction.`,
|
|
3483
|
+
`After the user reacts, call \`facilitate action=respond betEntryId="${b}" dimension="${nextDimension}" source="user_reaction"\` with their reaction.`,
|
|
3484
|
+
`If the user provides their own input instead, call with source="user".`
|
|
3485
|
+
].join("\n");
|
|
3486
|
+
}
|
|
3395
3487
|
return [
|
|
3396
3488
|
`Briefly synthesize what was just covered (2 lines max), then move to **${nextLabel}**.`,
|
|
3397
3489
|
`Ask ONE open question about ${nextLabel.toLowerCase()}. Keep it to 3 lines.`,
|
|
@@ -3499,7 +3591,7 @@ async function loadSessionDrafts(betEntryId, betInternalId) {
|
|
|
3499
3591
|
return [];
|
|
3500
3592
|
}
|
|
3501
3593
|
}
|
|
3502
|
-
function buildScoringContext(userInput, betData, constellation, overlapIds, chainSurfaced = [], activeDimension) {
|
|
3594
|
+
function buildScoringContext(userInput, betData, constellation, overlapIds, chainSurfaced = [], activeDimension, source = "user") {
|
|
3503
3595
|
const str = (key) => betData[key] ?? "";
|
|
3504
3596
|
const accParts = [
|
|
3505
3597
|
str("problem"),
|
|
@@ -3539,7 +3631,8 @@ function buildScoringContext(userInput, betData, constellation, overlapIds, chai
|
|
|
3539
3631
|
noGoCount,
|
|
3540
3632
|
governanceCount,
|
|
3541
3633
|
decisionCount: constellation.decisionCount,
|
|
3542
|
-
hasArchitectureText
|
|
3634
|
+
hasArchitectureText,
|
|
3635
|
+
source
|
|
3543
3636
|
};
|
|
3544
3637
|
}
|
|
3545
3638
|
async function searchOverlap(text) {
|
|
@@ -3632,6 +3725,12 @@ async function handleStart2(args) {
|
|
|
3632
3725
|
status: "draft",
|
|
3633
3726
|
data: {
|
|
3634
3727
|
problem: "",
|
|
3728
|
+
appetite: "",
|
|
3729
|
+
elements: "",
|
|
3730
|
+
rabbitHoles: "",
|
|
3731
|
+
noGos: "",
|
|
3732
|
+
architecture: "",
|
|
3733
|
+
buildContract: "",
|
|
3635
3734
|
description: `Shaping session for: ${betName}`,
|
|
3636
3735
|
status: "shaping",
|
|
3637
3736
|
shapingSessionActive: true
|
|
@@ -3652,6 +3751,10 @@ async function handleStart2(args) {
|
|
|
3652
3751
|
}
|
|
3653
3752
|
const studioUrl = buildStudioUrl(wsCtx.workspaceSlug, betEntryId);
|
|
3654
3753
|
const response = emptyResponse(betEntryId, studioUrl);
|
|
3754
|
+
const investigationBrief = buildInvestigationBrief("context", betName, betEntryId);
|
|
3755
|
+
if (investigationBrief) {
|
|
3756
|
+
response.investigationBrief = investigationBrief;
|
|
3757
|
+
}
|
|
3655
3758
|
const output = [
|
|
3656
3759
|
`# Shaping Session Started`,
|
|
3657
3760
|
"",
|
|
@@ -3665,9 +3768,10 @@ async function handleStart2(args) {
|
|
|
3665
3768
|
"",
|
|
3666
3769
|
"---",
|
|
3667
3770
|
"## Agent Directive",
|
|
3668
|
-
"
|
|
3669
|
-
"
|
|
3670
|
-
"
|
|
3771
|
+
"**Investigate first** \u2014 before asking the user, use the investigationBrief to search the codebase and Chain for context related to this bet.",
|
|
3772
|
+
"Spawn sub-agents: one `explore` agent to search the codebase, one `generalPurpose` agent to search the Chain.",
|
|
3773
|
+
"Synthesize findings into a 3-5 line context brief, then present to the user.",
|
|
3774
|
+
"After presenting context, ask: **What's not working well? Describe the problem \u2014 who's affected, and what's the workaround today?**",
|
|
3671
3775
|
"Keep your message to 5 lines or fewer. Heavy context degrades the shaping experience.",
|
|
3672
3776
|
`After the user responds, call \`facilitate action=respond betEntryId="${betEntryId}" dimension="problem_clarity"\` with their answer as userInput.`
|
|
3673
3777
|
].filter(Boolean).join("\n");
|
|
@@ -3678,7 +3782,8 @@ async function handleStart2(args) {
|
|
|
3678
3782
|
}
|
|
3679
3783
|
async function handleRespond(args) {
|
|
3680
3784
|
requireWriteAccess();
|
|
3681
|
-
const { userInput, betEntryId: argBetId, dimension: argDimension, capture: captureArg } = args;
|
|
3785
|
+
const { userInput, betEntryId: argBetId, dimension: argDimension, capture: captureArg, source: argSource } = args;
|
|
3786
|
+
const source = argSource ?? "user";
|
|
3682
3787
|
if (!userInput) {
|
|
3683
3788
|
return {
|
|
3684
3789
|
content: [{ type: "text", text: "`userInput` is required for respond action." }]
|
|
@@ -3695,7 +3800,7 @@ async function handleRespond(args) {
|
|
|
3695
3800
|
const [betEntry, constellation, overlap, chainSurfaced] = await Promise.all([
|
|
3696
3801
|
loadBetEntry(argBetId),
|
|
3697
3802
|
loadConstellationState(argBetId),
|
|
3698
|
-
searchOverlap(userInput),
|
|
3803
|
+
captureArg ? Promise.resolve([]) : searchOverlap(userInput),
|
|
3699
3804
|
gatherChainContext(userInput)
|
|
3700
3805
|
]);
|
|
3701
3806
|
if (!betEntry) {
|
|
@@ -3843,7 +3948,7 @@ async function handleRespond(args) {
|
|
|
3843
3948
|
if (argDimension && DIMENSIONS.includes(argDimension)) {
|
|
3844
3949
|
activeDimension = argDimension;
|
|
3845
3950
|
} else {
|
|
3846
|
-
const prelim = buildScoringContext(userInput, refreshedData, refreshedConstellation, overlapIds, chainSurfaced);
|
|
3951
|
+
const prelim = buildScoringContext(userInput, refreshedData, refreshedConstellation, overlapIds, chainSurfaced, void 0, source);
|
|
3847
3952
|
activeDimension = inferActiveDimension(buildScorecard(prelim), isSmallBatch);
|
|
3848
3953
|
}
|
|
3849
3954
|
const scoringCtx = buildScoringContext(
|
|
@@ -3852,7 +3957,8 @@ async function handleRespond(args) {
|
|
|
3852
3957
|
refreshedConstellation,
|
|
3853
3958
|
overlapIds,
|
|
3854
3959
|
chainSurfaced,
|
|
3855
|
-
activeDimension
|
|
3960
|
+
activeDimension,
|
|
3961
|
+
source
|
|
3856
3962
|
);
|
|
3857
3963
|
const dimensionResult = scoreDimension(activeDimension, scoringCtx);
|
|
3858
3964
|
const scorecard = buildScorecard(scoringCtx);
|
|
@@ -3869,10 +3975,7 @@ async function handleRespond(args) {
|
|
|
3869
3975
|
};
|
|
3870
3976
|
persist("problem_clarity", "problem", 50);
|
|
3871
3977
|
persist("appetite", "appetite", 20);
|
|
3872
|
-
persist("elements", "elements", 50);
|
|
3873
3978
|
persist("architecture", "architecture", 50);
|
|
3874
|
-
persist("risks", "rabbitHoles", 50);
|
|
3875
|
-
persist("boundaries", "noGos", 20);
|
|
3876
3979
|
if (overlapIds.length > 0 && !refreshedData._overlapIds) {
|
|
3877
3980
|
fieldUpdates._overlapIds = overlapIds.join(",");
|
|
3878
3981
|
}
|
|
@@ -3906,7 +4009,7 @@ async function handleRespond(args) {
|
|
|
3906
4009
|
const dims = activeDimensions(isSmallBatch);
|
|
3907
4010
|
const captureReady = completed.length >= (isSmallBatch ? 3 : 4) && dims.every((d) => scorecard[d] > 0);
|
|
3908
4011
|
const observation = dimensionResult.satisfied.length > 0 ? `${DIMENSION_LABELS[activeDimension]}: ${dimensionResult.satisfied.join("; ")}` : `${DIMENSION_LABELS[activeDimension]}: needs more detail`;
|
|
3909
|
-
const pushback = overlap.length > 0 ? `${overlap[0].summary} already exists on the Chain. How does your bet differ?` : dimensionResult.missing.length > 0 ? dimensionResult.missing[0] : "";
|
|
4012
|
+
const pushback = !captureArg && overlap.length > 0 ? `${overlap[0].summary} already exists on the Chain. How does your bet differ?` : dimensionResult.missing.length > 0 ? dimensionResult.missing[0] : "";
|
|
3910
4013
|
const suggestedQuestion = dimensionResult.missing.length > 1 ? dimensionResult.missing[1] : dimensionResult.missing.length > 0 ? dimensionResult.missing[0] : `${DIMENSION_LABELS[nextDimension]} is next \u2014 ready to move on?`;
|
|
3911
4014
|
const wsCtx = await getWorkspaceContext();
|
|
3912
4015
|
const studioUrl = buildStudioUrl(wsCtx.workspaceSlug, argBetId);
|
|
@@ -3922,6 +4025,8 @@ async function handleRespond(args) {
|
|
|
3922
4025
|
}
|
|
3923
4026
|
const suggested = suggestCaptures(scoringCtx, activeDimension);
|
|
3924
4027
|
const sessionDrafts = await loadSessionDrafts(argBetId, refreshedBet?._id ?? betEntry._id);
|
|
4028
|
+
const betName = refreshedData.description ?? betEntry.name;
|
|
4029
|
+
const investigationBrief = buildInvestigationBrief(phase, betName, argBetId) ?? void 0;
|
|
3925
4030
|
const response = {
|
|
3926
4031
|
phase,
|
|
3927
4032
|
phaseLabel: PHASE_LABELS[phase],
|
|
@@ -3951,12 +4056,21 @@ async function handleRespond(args) {
|
|
|
3951
4056
|
activeDimension,
|
|
3952
4057
|
suggestedOrder: dims
|
|
3953
4058
|
},
|
|
3954
|
-
buildContract
|
|
4059
|
+
buildContract,
|
|
4060
|
+
investigationBrief
|
|
4061
|
+
};
|
|
4062
|
+
const STRUCTURED_DIMS = {
|
|
4063
|
+
elements: "element",
|
|
4064
|
+
risks: "risk",
|
|
4065
|
+
boundaries: "noGo"
|
|
3955
4066
|
};
|
|
4067
|
+
const expectedCaptureType = STRUCTURED_DIMS[activeDimension];
|
|
4068
|
+
const dataLossWarning = expectedCaptureType && !captureArg ? `**WARNING:** You discussed ${activeDimension} but did not use the \`capture\` parameter \u2014 nothing was saved to the bet. Re-send with \`capture={type:"${expectedCaptureType}", name:"...", description:"..."}\` to persist this.` : "";
|
|
3956
4069
|
const directive = buildDirective(scorecard, phase, argBetId, captureReady, activeDimension, nextDimension);
|
|
3957
4070
|
const summaryParts = [
|
|
3958
4071
|
`# ${PHASE_LABELS[phase]} \u2014 ${DIMENSION_LABELS[activeDimension]}`,
|
|
3959
4072
|
"",
|
|
4073
|
+
dataLossWarning,
|
|
3960
4074
|
`**Score:** ${scorecard[activeDimension]}/10 | **Phase:** ${PHASE_LABELS[phase]}`,
|
|
3961
4075
|
observation,
|
|
3962
4076
|
pushback ? `**Pushback:** ${pushback}` : "",
|
|
@@ -3969,7 +4083,13 @@ async function handleRespond(args) {
|
|
|
3969
4083
|
directive ? `
|
|
3970
4084
|
---
|
|
3971
4085
|
## Agent Directive
|
|
3972
|
-
${directive}` : ""
|
|
4086
|
+
${directive}` : "",
|
|
4087
|
+
investigationBrief ? `
|
|
4088
|
+
## Investigation Brief
|
|
4089
|
+
${investigationBrief.tasks.map((t) => `- **${t.target}:** ${t.query} \u2014 ${t.purpose}`).join("\n")}
|
|
4090
|
+
|
|
4091
|
+
**Proposal guidance:** ${investigationBrief.proposalGuidance}
|
|
4092
|
+
**Reaction prompt:** ${investigationBrief.reactionPrompt}` : ""
|
|
3973
4093
|
];
|
|
3974
4094
|
return {
|
|
3975
4095
|
content: [{ type: "text", text: summaryParts.filter(Boolean).join("\n") }],
|
|
@@ -6983,6 +7103,12 @@ function registerHealthTools(server) {
|
|
|
6983
7103
|
async ({ mode = "full", task } = {}) => {
|
|
6984
7104
|
const errors = [];
|
|
6985
7105
|
const agentSessionId = getAgentSessionId();
|
|
7106
|
+
if (isSessionOriented() && mode === "brief" && !task) {
|
|
7107
|
+
return {
|
|
7108
|
+
content: [{ type: "text", text: "Already oriented. Session active, writes unlocked. Use `orient mode='full'` or `orient task='...'` for full context." }],
|
|
7109
|
+
structuredContent: { alreadyOriented: true, sessionId: agentSessionId }
|
|
7110
|
+
};
|
|
7111
|
+
}
|
|
6986
7112
|
let wsCtx = null;
|
|
6987
7113
|
try {
|
|
6988
7114
|
wsCtx = await getWorkspaceContext();
|
|
@@ -8082,8 +8208,13 @@ Each scored 0-10 by the server:
|
|
|
8082
8208
|
|
|
8083
8209
|
2. **Respond (repeat):** \`facilitate action=respond betEntryId="..." userInput="<user's input>"\`
|
|
8084
8210
|
Optionally add \`dimension="problem_clarity"\` to target a specific dimension.
|
|
8085
|
-
|
|
8086
|
-
|
|
8211
|
+
|
|
8212
|
+
**CRITICAL \u2014 Capture is REQUIRED for structured items:**
|
|
8213
|
+
Elements, risks, and no-gos MUST include the \`capture\` parameter. Without it, nothing is saved to the bet \u2014 the data is silently lost and you will receive a WARNING.
|
|
8214
|
+
- Elements: \`capture={type:"element", name:"...", description:"..."}\`
|
|
8215
|
+
- Risks: \`capture={type:"risk", name:"...", description:"...", theme:"implementation"}\`
|
|
8216
|
+
- No-gos: \`capture={type:"noGo", name:"...", description:"..."}\`
|
|
8217
|
+
Each element, risk, and no-go needs its own \`respond\` call with \`capture\`.
|
|
8087
8218
|
|
|
8088
8219
|
3. **Score (anytime):** \`facilitate action=score betEntryId="..."\`
|
|
8089
8220
|
Check the scorecard without advancing.
|
|
@@ -8345,7 +8476,7 @@ If ready, ask the user to confirm. If not, suggest specific improvements.
|
|
|
8345
8476
|
}
|
|
8346
8477
|
|
|
8347
8478
|
// src/server.ts
|
|
8348
|
-
var SERVER_VERSION = "0.7.
|
|
8479
|
+
var SERVER_VERSION = "0.7.2";
|
|
8349
8480
|
var INSTRUCTIONS = [
|
|
8350
8481
|
"Product Brain \u2014 the single source of truth for product knowledge.",
|
|
8351
8482
|
"Terminology, standards, and core data all live here \u2014 no need to check external docs.",
|
|
@@ -8456,4 +8587,4 @@ export {
|
|
|
8456
8587
|
SERVER_VERSION,
|
|
8457
8588
|
createProductBrainServer
|
|
8458
8589
|
};
|
|
8459
|
-
//# sourceMappingURL=chunk-
|
|
8590
|
+
//# sourceMappingURL=chunk-HTL6Y2AO.js.map
|