@productbrain/cli 0.1.0-beta.36 → 0.1.0-beta.38

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.
Files changed (100) hide show
  1. package/dist/__tests__/experiment.test.d.ts +6 -0
  2. package/dist/__tests__/experiment.test.d.ts.map +1 -0
  3. package/dist/__tests__/experiment.test.js +69 -0
  4. package/dist/__tests__/experiment.test.js.map +1 -0
  5. package/dist/__tests__/onboarding-path-b.test.d.ts +2 -0
  6. package/dist/__tests__/onboarding-path-b.test.d.ts.map +1 -0
  7. package/dist/__tests__/onboarding-path-b.test.js +46 -0
  8. package/dist/__tests__/onboarding-path-b.test.js.map +1 -0
  9. package/dist/__tests__/onboarding.test.js +242 -89
  10. package/dist/__tests__/onboarding.test.js.map +1 -1
  11. package/dist/__tests__/setup.test.js +15 -6
  12. package/dist/__tests__/setup.test.js.map +1 -1
  13. package/dist/commands/connect-integration.test.d.ts +7 -0
  14. package/dist/commands/connect-integration.test.d.ts.map +1 -0
  15. package/dist/commands/connect-integration.test.js +148 -0
  16. package/dist/commands/connect-integration.test.js.map +1 -0
  17. package/dist/commands/connect.d.ts +17 -0
  18. package/dist/commands/connect.d.ts.map +1 -0
  19. package/dist/commands/connect.js +280 -0
  20. package/dist/commands/connect.js.map +1 -0
  21. package/dist/commands/connect.test.d.ts +6 -0
  22. package/dist/commands/connect.test.d.ts.map +1 -0
  23. package/dist/commands/connect.test.js +230 -0
  24. package/dist/commands/connect.test.js.map +1 -0
  25. package/dist/commands/handshake.d.ts +2 -0
  26. package/dist/commands/handshake.d.ts.map +1 -1
  27. package/dist/commands/handshake.js +20 -5
  28. package/dist/commands/handshake.js.map +1 -1
  29. package/dist/commands/setup.d.ts.map +1 -1
  30. package/dist/commands/setup.js +29 -2
  31. package/dist/commands/setup.js.map +1 -1
  32. package/dist/generators/chain-classifier.d.ts +1 -1
  33. package/dist/generators/chain-classifier.d.ts.map +1 -1
  34. package/dist/generators/context-md.d.ts +1 -1
  35. package/dist/generators/context-md.d.ts.map +1 -1
  36. package/dist/generators/context-md.js +12 -1
  37. package/dist/generators/context-md.js.map +1 -1
  38. package/dist/index.js +14 -2
  39. package/dist/index.js.map +1 -1
  40. package/dist/lib/config.d.ts +1 -0
  41. package/dist/lib/config.d.ts.map +1 -1
  42. package/dist/lib/config.js +25 -1
  43. package/dist/lib/config.js.map +1 -1
  44. package/dist/lib/conversation-engine.d.ts +22 -27
  45. package/dist/lib/conversation-engine.d.ts.map +1 -1
  46. package/dist/lib/conversation-engine.js +58 -80
  47. package/dist/lib/conversation-engine.js.map +1 -1
  48. package/dist/lib/conversation-phases.d.ts +22 -37
  49. package/dist/lib/conversation-phases.d.ts.map +1 -1
  50. package/dist/lib/conversation-phases.js +4 -4
  51. package/dist/lib/conversation-signals.d.ts +3 -0
  52. package/dist/lib/conversation-signals.d.ts.map +1 -1
  53. package/dist/lib/conversation-signals.js +14 -3
  54. package/dist/lib/conversation-signals.js.map +1 -1
  55. package/dist/lib/experiment.d.ts +18 -0
  56. package/dist/lib/experiment.d.ts.map +1 -0
  57. package/dist/lib/experiment.js +28 -0
  58. package/dist/lib/experiment.js.map +1 -0
  59. package/dist/lib/onboarding-path-b.d.ts +10 -0
  60. package/dist/lib/onboarding-path-b.d.ts.map +1 -0
  61. package/dist/lib/onboarding-path-b.js +214 -0
  62. package/dist/lib/onboarding-path-b.js.map +1 -0
  63. package/dist/lib/onboarding-phases.js +1 -1
  64. package/dist/lib/onboarding-shared.d.ts +81 -0
  65. package/dist/lib/onboarding-shared.d.ts.map +1 -0
  66. package/dist/lib/onboarding-shared.js +190 -0
  67. package/dist/lib/onboarding-shared.js.map +1 -0
  68. package/dist/lib/onboarding-topics.d.ts +27 -0
  69. package/dist/lib/onboarding-topics.d.ts.map +1 -0
  70. package/dist/lib/onboarding-topics.js +57 -0
  71. package/dist/lib/onboarding-topics.js.map +1 -0
  72. package/dist/lib/onboarding.d.ts +3 -3
  73. package/dist/lib/onboarding.d.ts.map +1 -1
  74. package/dist/lib/onboarding.js +109 -240
  75. package/dist/lib/onboarding.js.map +1 -1
  76. package/dist/lib/profiles.d.ts +5 -0
  77. package/dist/lib/profiles.d.ts.map +1 -1
  78. package/dist/lib/profiles.js +7 -0
  79. package/dist/lib/profiles.js.map +1 -1
  80. package/dist/lib/telemetry.d.ts +5 -5
  81. package/dist/lib/telemetry.d.ts.map +1 -1
  82. package/dist/lib/telemetry.js +34 -16
  83. package/dist/lib/telemetry.js.map +1 -1
  84. package/dist/lib/wizard-surfaces.d.ts +47 -0
  85. package/dist/lib/wizard-surfaces.d.ts.map +1 -0
  86. package/dist/lib/wizard-surfaces.js +176 -0
  87. package/dist/lib/wizard-surfaces.js.map +1 -0
  88. package/dist/lib/wizard-surfaces.test.d.ts +2 -0
  89. package/dist/lib/wizard-surfaces.test.d.ts.map +1 -0
  90. package/dist/lib/wizard-surfaces.test.js +127 -0
  91. package/dist/lib/wizard-surfaces.test.js.map +1 -0
  92. package/dist/lib/wizard-trust.d.ts +31 -0
  93. package/dist/lib/wizard-trust.d.ts.map +1 -0
  94. package/dist/lib/wizard-trust.js +66 -0
  95. package/dist/lib/wizard-trust.js.map +1 -0
  96. package/dist/lib/wizard-trust.test.d.ts +2 -0
  97. package/dist/lib/wizard-trust.test.d.ts.map +1 -0
  98. package/dist/lib/wizard-trust.test.js +32 -0
  99. package/dist/lib/wizard-trust.test.js.map +1 -0
  100. package/package.json +1 -1
@@ -1,40 +1,17 @@
1
1
  /**
2
- * Conversation phase types — reusable phase-gated conversation control.
2
+ * Conversation types — state and signal types for coach-pattern conversations.
3
3
  * WP-304: LLM owns content, CLI owns flow.
4
4
  *
5
5
  * Pattern: Deterministic Shell, Stochastic Core.
6
- * - CLI defines phases with exit criteria (deterministic)
7
- * - LLM generates conversation content within each phase (stochastic)
8
- * - CLI evaluates criteria and decides when to advance
6
+ * - CLI defines topics with goal/behaviour/criteria (deterministic)
7
+ * - LLM generates conversation content and judges criteria (stochastic)
8
+ * - CLI evaluates with heuristic backup and decides when to advance
9
9
  */
10
- /** A conversation phase with a directive and exit criteria. */
11
- export interface ConversationPhase {
12
- /** Unique phase identifier. */
13
- id: string;
14
- /**
15
- * Injected into the system prompt. Tells the LLM what this phase
16
- * is about and what kind of questions to ask.
17
- */
18
- directive: string;
19
- /**
20
- * CLI-enforced exit criteria. Required ones must pass to advance.
21
- * Non-required ones are advisory — help quality but don't block.
22
- */
23
- exitCriteria: ExitCriterion[];
24
- /**
25
- * Max exchanges in this phase before forced advancement.
26
- * Prevents getting stuck with uncooperative users.
27
- */
28
- maxExchanges: number;
29
- }
30
- /** An exit criterion — pure function over conversation state. */
31
- export interface ExitCriterion {
32
- /** Human-readable name for debugging. */
33
- name: string;
34
- /** Returns true when the criterion is met. */
35
- check: (state: ConversationState) => boolean;
36
- /** If true, forced advancement cannot skip this. */
37
- required: boolean;
10
+ /** A completed topic's question-answer pair, accumulated as context for later topics. */
11
+ export interface TopicQA {
12
+ topicId: string;
13
+ question: string;
14
+ answer: string;
38
15
  }
39
16
  /** Conversation state — the CLI's accumulated view of the conversation. */
40
17
  export interface ConversationState {
@@ -47,12 +24,20 @@ export interface ConversationState {
47
24
  userMessageCount: number;
48
25
  /** Total user words total. */
49
26
  totalUserWords: number;
50
- /** Exchange count per phase. */
27
+ /** Exchange count per topic (coach pattern) or phase (legacy). */
28
+ topicExchanges: Record<string, number>;
29
+ /** @deprecated Alias for topicExchanges — used by legacy phase engine until Slice 3. */
51
30
  phaseExchanges: Record<string, number>;
52
- /** Which phases have been completed. */
31
+ /** Which topics have been completed. */
32
+ completedTopics: Set<string>;
33
+ /** @deprecated Alias for completedTopics — used by legacy phase engine until Slice 3. */
53
34
  completedPhases: Set<string>;
54
- /** Current phase ID. */
35
+ /** Current topic ID. */
36
+ currentTopicId: string;
37
+ /** @deprecated Alias for currentTopicId — used by legacy phase engine until Slice 3. */
55
38
  currentPhaseId: string;
39
+ /** Completed topic Q&A pairs — accumulated context for later topics. */
40
+ completedQA: TopicQA[];
56
41
  /** Heuristic signals detected from user messages. */
57
42
  signals: ConversationSignals;
58
43
  /** Count of consecutive refusals/non-answers. */
@@ -66,9 +51,9 @@ export interface ConversationSignals {
66
51
  mentionedChallenge: boolean;
67
52
  /** User mentioned why they're trying Product Brain. */
68
53
  mentionedWhyPB: boolean;
69
- /** User gave at least one substantive answer (>= 8 words). */
54
+ /** User gave at least one substantive answer (>= 15 words). */
70
55
  hasSubstantiveAnswer: boolean;
71
- /** Number of user messages with >= 5 words. */
56
+ /** Number of user messages with >= 8 words. */
72
57
  substantiveMessageCount: number;
73
58
  }
74
59
  //# sourceMappingURL=conversation-phases.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-phases.d.ts","sourceRoot":"","sources":["../../src/lib/conversation-phases.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAC;IAEX;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,YAAY,EAAE,aAAa,EAAE,CAAC;IAE9B;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IAEb,8CAA8C;IAC9C,KAAK,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC;IAE7C,oDAAoD;IACpD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC,2BAA2B;IAC3B,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEjE,qCAAqC;IACrC,gBAAgB,EAAE,MAAM,CAAC;IAEzB,8BAA8B;IAC9B,cAAc,EAAE,MAAM,CAAC;IAEvB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEvC,wCAAwC;IACxC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAE7B,wBAAwB;IACxB,cAAc,EAAE,MAAM,CAAC;IAEvB,qDAAqD;IACrD,OAAO,EAAE,mBAAmB,CAAC;IAE7B,iDAAiD;IACjD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,sEAAsE;AACtE,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,gBAAgB,EAAE,OAAO,CAAC;IAE1B,0DAA0D;IAC1D,kBAAkB,EAAE,OAAO,CAAC;IAE5B,uDAAuD;IACvD,cAAc,EAAE,OAAO,CAAC;IAExB,8DAA8D;IAC9D,oBAAoB,EAAE,OAAO,CAAC;IAE9B,+CAA+C;IAC/C,uBAAuB,EAAE,MAAM,CAAC;CACjC"}
1
+ {"version":3,"file":"conversation-phases.d.ts","sourceRoot":"","sources":["../../src/lib/conversation-phases.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yFAAyF;AACzF,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC,2BAA2B;IAC3B,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEjE,qCAAqC;IACrC,gBAAgB,EAAE,MAAM,CAAC;IAEzB,8BAA8B;IAC9B,cAAc,EAAE,MAAM,CAAC;IAEvB,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,wFAAwF;IACxF,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEvC,wCAAwC;IACxC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,yFAAyF;IACzF,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAE7B,wBAAwB;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,wFAAwF;IACxF,cAAc,EAAE,MAAM,CAAC;IAEvB,wEAAwE;IACxE,WAAW,EAAE,OAAO,EAAE,CAAC;IAEvB,qDAAqD;IACrD,OAAO,EAAE,mBAAmB,CAAC;IAE7B,iDAAiD;IACjD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,sEAAsE;AACtE,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,gBAAgB,EAAE,OAAO,CAAC;IAE1B,0DAA0D;IAC1D,kBAAkB,EAAE,OAAO,CAAC;IAE5B,uDAAuD;IACvD,cAAc,EAAE,OAAO,CAAC;IAExB,+DAA+D;IAC/D,oBAAoB,EAAE,OAAO,CAAC;IAE9B,+CAA+C;IAC/C,uBAAuB,EAAE,MAAM,CAAC;CACjC"}
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Conversation phase types — reusable phase-gated conversation control.
2
+ * Conversation types — state and signal types for coach-pattern conversations.
3
3
  * WP-304: LLM owns content, CLI owns flow.
4
4
  *
5
5
  * Pattern: Deterministic Shell, Stochastic Core.
6
- * - CLI defines phases with exit criteria (deterministic)
7
- * - LLM generates conversation content within each phase (stochastic)
8
- * - CLI evaluates criteria and decides when to advance
6
+ * - CLI defines topics with goal/behaviour/criteria (deterministic)
7
+ * - LLM generates conversation content and judges criteria (stochastic)
8
+ * - CLI evaluates with heuristic backup and decides when to advance
9
9
  */
10
10
  export {};
11
11
  //# sourceMappingURL=conversation-phases.js.map
@@ -10,6 +10,9 @@ import type { ConversationSignals } from './conversation-phases.js';
10
10
  /**
11
11
  * Detect signals from user messages using regex heuristics.
12
12
  * Returns accumulated signals across all user messages.
13
+ *
14
+ * Thresholds are intentionally strict — we'd rather ask one more question
15
+ * than advance on a vague answer. maxExchanges is the safety valve.
13
16
  */
14
17
  export declare function detectSignals(messages: Array<{
15
18
  role: string;
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-signals.d.ts","sourceRoot":"","sources":["../../src/lib/conversation-signals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAwBpE;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,mBAAmB,CAUrG;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,mBAAmB,EAC9B,UAAU,EAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9F,mBAAmB,CAOrB"}
1
+ {"version":3,"file":"conversation-signals.d.ts","sourceRoot":"","sources":["../../src/lib/conversation-signals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AA4BpE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,mBAAmB,CAgBrG;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,mBAAmB,EAC9B,UAAU,EAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9F,mBAAmB,CAOrB"}
@@ -20,6 +20,10 @@ const WHY_PB_PATTERNS = [
20
20
  /\b(?:context|memory|decisions?|knowledge|source of truth|ssot)\b/i,
21
21
  /\b(?:ai|llm|claude|cursor|copilot|agent)\b.*\b(?:context|remember|forget|know)\b/i,
22
22
  /\b(?:remember|forget|consistent|prompt)\b.*\b(?:ai|llm|agent|tool)\b/i,
23
+ // Broader: user describes the problem PB solves without naming PB
24
+ /\b(?:re-?explain|repeat myself|start from (?:zero|scratch)|re-?tell)\b/i,
25
+ /\b(?:docs?|documentation|md files?)\b.*\b(?:outdated|stale|rot|drift|wrong|maintain)\b/i,
26
+ /\b(?:cost|waste|spend)\b.*\b(?:tokens?|context|time)\b.*\b(?:re-?explain|repeat|maintain)\b/i,
23
27
  ];
24
28
  function countWords(text) {
25
29
  return text.trim().split(/\s+/).filter(Boolean).length;
@@ -27,15 +31,22 @@ function countWords(text) {
27
31
  /**
28
32
  * Detect signals from user messages using regex heuristics.
29
33
  * Returns accumulated signals across all user messages.
34
+ *
35
+ * Thresholds are intentionally strict — we'd rather ask one more question
36
+ * than advance on a vague answer. maxExchanges is the safety valve.
30
37
  */
31
38
  export function detectSignals(messages) {
32
39
  const userMessages = messages.filter((m) => m.role === 'user');
33
40
  return {
34
- mentionedProduct: userMessages.some((m) => PRODUCT_PATTERNS.some((p) => p.test(m.content))),
41
+ // Product mention requires BOTH a pattern match AND enough words to be meaningful.
42
+ // "a cool app" matches the pattern but isn't substantive — need at least 10 words.
43
+ mentionedProduct: userMessages.some((m) => PRODUCT_PATTERNS.some((p) => p.test(m.content)) && countWords(m.content) >= 10),
35
44
  mentionedChallenge: userMessages.some((m) => CHALLENGE_PATTERNS.some((p) => p.test(m.content))),
36
45
  mentionedWhyPB: userMessages.some((m) => WHY_PB_PATTERNS.some((p) => p.test(m.content))),
37
- hasSubstantiveAnswer: userMessages.some((m) => countWords(m.content) >= 8),
38
- substantiveMessageCount: userMessages.filter((m) => countWords(m.content) >= 5).length,
46
+ // Substantive = enough detail to extract something meaningful from
47
+ hasSubstantiveAnswer: userMessages.some((m) => countWords(m.content) >= 15),
48
+ // Count messages with real content (not just "me" or "yes")
49
+ substantiveMessageCount: userMessages.filter((m) => countWords(m.content) >= 8).length,
39
50
  };
40
51
  }
41
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-signals.js","sourceRoot":"","sources":["../../src/lib/conversation-signals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,gBAAgB,GAAG;IACvB,yDAAyD;IACzD,qEAAqE;CACtE,CAAC;AAEF,MAAM,kBAAkB,GAAG;IACzB,wFAAwF;IACxF,kFAAkF;IAClF,kDAAkD;CACnD,CAAC;AAEF,MAAM,eAAe,GAAG;IACtB,8BAA8B;IAC9B,mEAAmE;IACnE,mFAAmF;IACnF,uEAAuE;CACxE,CAAC;AAEF,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,QAAkD;IAC9E,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAE/D,OAAO;QACL,gBAAgB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3F,kBAAkB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/F,cAAc,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACxF,oBAAoB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1E,uBAAuB,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;KACvF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,SAA8B,EAC9B,UAA+F;IAE/F,OAAO;QACL,GAAG,SAAS;QACZ,gBAAgB,EAAE,SAAS,CAAC,gBAAgB,IAAI,CAAC,UAAU,CAAC,gBAAgB,IAAI,KAAK,CAAC;QACtF,kBAAkB,EAAE,SAAS,CAAC,kBAAkB,IAAI,CAAC,UAAU,CAAC,gBAAgB,IAAI,KAAK,CAAC;QAC1F,cAAc,EAAE,SAAS,CAAC,cAAc,IAAI,CAAC,UAAU,CAAC,aAAa,IAAI,KAAK,CAAC;KAChF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"conversation-signals.js","sourceRoot":"","sources":["../../src/lib/conversation-signals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,gBAAgB,GAAG;IACvB,yDAAyD;IACzD,qEAAqE;CACtE,CAAC;AAEF,MAAM,kBAAkB,GAAG;IACzB,wFAAwF;IACxF,kFAAkF;IAClF,kDAAkD;CACnD,CAAC;AAEF,MAAM,eAAe,GAAG;IACtB,8BAA8B;IAC9B,mEAAmE;IACnE,mFAAmF;IACnF,uEAAuE;IACvE,kEAAkE;IAClE,yEAAyE;IACzE,yFAAyF;IACzF,8FAA8F;CAC/F,CAAC;AAEF,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;AACzD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,QAAkD;IAC9E,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAE/D,OAAO;QACL,mFAAmF;QACnF,mFAAmF;QACnF,gBAAgB,EAAE,YAAY,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CACtF;QACD,kBAAkB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/F,cAAc,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACxF,mEAAmE;QACnE,oBAAoB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC3E,4DAA4D;QAC5D,uBAAuB,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;KACvF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,SAA8B,EAC9B,UAA+F;IAE/F,OAAO;QACL,GAAG,SAAS;QACZ,gBAAgB,EAAE,SAAS,CAAC,gBAAgB,IAAI,CAAC,UAAU,CAAC,gBAAgB,IAAI,KAAK,CAAC;QACtF,kBAAkB,EAAE,SAAS,CAAC,kBAAkB,IAAI,CAAC,UAAU,CAAC,gBAAgB,IAAI,KAAK,CAAC;QAC1F,cAAc,EAAE,SAAS,CAAC,cAAc,IAAI,CAAC,UAAU,CAAC,aAAa,IAAI,KAAK,CAAC;KAChF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Experiment assignment — deterministic path selection for A/B experiments.
3
+ * WP-304: Dormant until PB_EXPERIMENT_304=1. When active, overrides PB_ONBOARDING_PATH.
4
+ */
5
+ export type ExperimentPath = 'A' | 'B';
6
+ /**
7
+ * Deterministic assignment based on workspace ID.
8
+ * FNV-1a hash mod 2 — same workspace always gets the same path.
9
+ */
10
+ export declare function assignOnboardingPath(workspaceId: string): ExperimentPath;
11
+ /** Check if the WP-304 experiment is active. */
12
+ export declare function isExperimentActive(): boolean;
13
+ /**
14
+ * FNV-1a hash — fast, deterministic, good distribution for short strings.
15
+ * Returns a positive 32-bit integer.
16
+ */
17
+ export declare function fnv1aHash(str: string): number;
18
+ //# sourceMappingURL=experiment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experiment.d.ts","sourceRoot":"","sources":["../../src/lib/experiment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,cAAc,GAAG,GAAG,GAAG,GAAG,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAExE;AAED,gDAAgD;AAChD,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO7C"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Experiment assignment — deterministic path selection for A/B experiments.
3
+ * WP-304: Dormant until PB_EXPERIMENT_304=1. When active, overrides PB_ONBOARDING_PATH.
4
+ */
5
+ /**
6
+ * Deterministic assignment based on workspace ID.
7
+ * FNV-1a hash mod 2 — same workspace always gets the same path.
8
+ */
9
+ export function assignOnboardingPath(workspaceId) {
10
+ return fnv1aHash(workspaceId) % 2 === 0 ? 'A' : 'B';
11
+ }
12
+ /** Check if the WP-304 experiment is active. */
13
+ export function isExperimentActive() {
14
+ return process.env.PB_EXPERIMENT_304 === '1';
15
+ }
16
+ /**
17
+ * FNV-1a hash — fast, deterministic, good distribution for short strings.
18
+ * Returns a positive 32-bit integer.
19
+ */
20
+ export function fnv1aHash(str) {
21
+ let hash = 0x811c9dc5; // FNV offset basis
22
+ for (let i = 0; i < str.length; i++) {
23
+ hash ^= str.charCodeAt(i);
24
+ hash = (hash * 0x01000193) >>> 0; // FNV prime, keep as unsigned 32-bit
25
+ }
26
+ return hash >>> 0;
27
+ }
28
+ //# sourceMappingURL=experiment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experiment.js","sourceRoot":"","sources":["../../src/lib/experiment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,OAAO,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACtD,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,GAAG,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,IAAI,GAAG,UAAU,CAAC,CAAC,mBAAmB;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,GAAG,CAAC,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,qCAAqC;IACzE,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,CAAC;AACpB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Path B — Facilitator-pattern onboarding (2 exchanges max).
3
+ * WP-304: Shorter flow, silent extraction, auto-capture, governance proof.
4
+ */
5
+ import { type OnboardingExtraction } from './onboarding-shared.js';
6
+ export declare function runOnboardingPathB(workspaceName: string): Promise<void>;
7
+ /** Merge two extractions — second takes precedence for scalar fields, arrays concatenate. */
8
+ export declare function mergeExtractions(first: OnboardingExtraction | null, second: OnboardingExtraction): OnboardingExtraction;
9
+ export declare function dedupe(arr: string[]): string[];
10
+ //# sourceMappingURL=onboarding-path-b.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding-path-b.d.ts","sourceRoot":"","sources":["../../src/lib/onboarding-path-b.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAIL,KAAK,oBAAoB,EAG1B,MAAM,wBAAwB,CAAC;AAEhC,wBAAsB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyK7E;AAED,6FAA6F;AAC7F,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,oBAAoB,GAAG,IAAI,EAClC,MAAM,EAAE,oBAAoB,GAC3B,oBAAoB,CAUtB;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAI9C"}
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Path B — Facilitator-pattern onboarding (2 exchanges max).
3
+ * WP-304: Shorter flow, silent extraction, auto-capture, governance proof.
4
+ */
5
+ import { mcpCall } from './client.js';
6
+ import { ask } from './prompts.js';
7
+ import { bold, dim, green, icons } from './style.js';
8
+ import { trackEvent } from './telemetry.js';
9
+ import { extractionToEntries, batchCaptureEntries, countWords, } from './onboarding-shared.js';
10
+ export async function runOnboardingPathB(workspaceName) {
11
+ trackEvent('setup_started', { mode: 'llm', path: 'B' });
12
+ const messages = [];
13
+ let totalUserWords = 0;
14
+ let lastExtraction = null;
15
+ // Exchange 1: Opening question
16
+ let greeting;
17
+ try {
18
+ const result = await mcpCall('onboarding.chat', {
19
+ messages: [],
20
+ workspaceName,
21
+ style: 'facilitator',
22
+ turnNumber: 1,
23
+ totalUserWords: 0,
24
+ });
25
+ if (!result?.content) {
26
+ await runPathBFallback(workspaceName);
27
+ return;
28
+ }
29
+ greeting = result.content;
30
+ }
31
+ catch {
32
+ await runPathBFallback(workspaceName);
33
+ return;
34
+ }
35
+ process.stdout.write(`\n ${greeting}\n\n`);
36
+ messages.push({ role: 'assistant', content: greeting });
37
+ // Get user's first answer
38
+ let userInput;
39
+ try {
40
+ userInput = await ask({
41
+ message: 'You',
42
+ placeholder: 'Tell me about your product...',
43
+ });
44
+ }
45
+ catch {
46
+ process.stdout.write(`\n ${dim('No worries! Run')} ${bold('pb capture')} ${dim('anytime to add knowledge.')}\n\n`);
47
+ return;
48
+ }
49
+ if (!userInput.trim()) {
50
+ process.stdout.write(`\n ${dim('No problem — explore with')} ${bold('pb orient -b')} ${dim('or capture with')} ${bold('pb capture')}\n\n`);
51
+ return;
52
+ }
53
+ messages.push({ role: 'user', content: userInput });
54
+ totalUserWords += countWords(userInput);
55
+ // Silent extraction after first answer (parallel with follow-up)
56
+ const [followUpResult, extractResult] = await Promise.allSettled([
57
+ mcpCall('onboarding.chat', {
58
+ messages,
59
+ workspaceName,
60
+ style: 'facilitator',
61
+ turnNumber: 2,
62
+ totalUserWords,
63
+ }),
64
+ mcpCall('onboarding.chat', {
65
+ messages,
66
+ workspaceName,
67
+ mode: 'extract',
68
+ }),
69
+ ]);
70
+ // Store first extraction if available
71
+ if (extractResult.status === 'fulfilled' && extractResult.value?.extraction) {
72
+ lastExtraction = extractResult.value.extraction;
73
+ }
74
+ // Show follow-up question
75
+ if (followUpResult.status === 'fulfilled' && followUpResult.value?.content) {
76
+ const followUp = followUpResult.value.content;
77
+ process.stdout.write(`\n ${followUp}\n\n`);
78
+ messages.push({ role: 'assistant', content: followUp });
79
+ // Get second answer
80
+ try {
81
+ const secondInput = await ask({ message: 'You', placeholder: '' });
82
+ if (secondInput.trim()) {
83
+ messages.push({ role: 'user', content: secondInput });
84
+ totalUserWords += countWords(secondInput);
85
+ // Second extraction — merge with first
86
+ try {
87
+ const result2 = await mcpCall('onboarding.chat', {
88
+ messages,
89
+ workspaceName,
90
+ mode: 'extract',
91
+ });
92
+ if (result2?.extraction) {
93
+ lastExtraction = mergeExtractions(lastExtraction, result2.extraction);
94
+ }
95
+ }
96
+ catch {
97
+ // Use first extraction if second fails
98
+ }
99
+ }
100
+ }
101
+ catch {
102
+ // User cancelled — use what we have
103
+ }
104
+ }
105
+ // Content floor — need at least something to extract
106
+ if (totalUserWords < 5 || !lastExtraction?.vision) {
107
+ // Try one final extraction if we don't have one
108
+ if (!lastExtraction?.vision && messages.filter((m) => m.role === 'user').length > 0) {
109
+ try {
110
+ const finalExtract = await mcpCall('onboarding.chat', {
111
+ messages,
112
+ workspaceName,
113
+ mode: 'extract',
114
+ });
115
+ if (finalExtract?.extraction) {
116
+ lastExtraction = finalExtract.extraction;
117
+ }
118
+ }
119
+ catch {
120
+ // Nothing to do
121
+ }
122
+ }
123
+ if (!lastExtraction?.vision) {
124
+ process.stdout.write(`\n ${dim('No problem — add knowledge anytime with')} ${bold('pb capture')}\n\n`);
125
+ trackEvent('setup_completed', { path: 'B', capturedCount: 0, reason: 'insufficient_content' });
126
+ return;
127
+ }
128
+ }
129
+ trackEvent('first_capture_prompted', { mode: 'llm', path: 'B' });
130
+ // Auto-capture — no approval UI in Path B
131
+ const allEntries = extractionToEntries(lastExtraction);
132
+ const entriesToCapture = allEntries
133
+ .filter((e) => e.name.trim().split(/\s+/).length >= 2 || e.collection === 'glossary')
134
+ .slice(0, 5);
135
+ if (entriesToCapture.length === 0) {
136
+ process.stdout.write(`\n ${dim('Nothing to save yet. Try')} ${bold('pb capture')} ${dim('to add knowledge manually.')}\n\n`);
137
+ return;
138
+ }
139
+ const { capturedCount, errors } = await batchCaptureEntries(entriesToCapture);
140
+ if (capturedCount > 0) {
141
+ process.stdout.write(`\n ${green(icons.pass)} Saved ${capturedCount} item${capturedCount === 1 ? '' : 's'} to your product brain.\n`);
142
+ trackEvent('capture_completed', { mode: 'llm', path: 'B', count: capturedCount });
143
+ }
144
+ if (errors.length > 0) {
145
+ process.stdout.write(`\n ${dim(`${errors.length} couldn't be saved.`)}\n`);
146
+ }
147
+ // Governance proof moment — show how captured knowledge participates in governance
148
+ await showGovernanceProof(lastExtraction.vision);
149
+ process.stdout.write(` ${dim('Explore with')} ${bold('pb orient -b')} ${dim('or add more with')} ${bold('pb capture')}\n\n`);
150
+ trackEvent('setup_completed', { path: 'B', capturedCount });
151
+ }
152
+ /** Merge two extractions — second takes precedence for scalar fields, arrays concatenate. */
153
+ export function mergeExtractions(first, second) {
154
+ if (!first)
155
+ return second;
156
+ return {
157
+ vision: second.vision || first.vision,
158
+ audience: second.audience || first.audience,
159
+ techStack: dedupe([...(first.techStack ?? []), ...(second.techStack ?? [])]),
160
+ keyTerms: dedupe([...(first.keyTerms ?? []), ...(second.keyTerms ?? [])]),
161
+ keyDecisions: dedupe([...(first.keyDecisions ?? []), ...(second.keyDecisions ?? [])]),
162
+ tensions: dedupe([...(first.tensions ?? []), ...(second.tensions ?? [])]),
163
+ };
164
+ }
165
+ export function dedupe(arr) {
166
+ return [...new Set(arr.map((s) => s.toLowerCase()))].map((lower) => arr.find((s) => s.toLowerCase() === lower) ?? lower);
167
+ }
168
+ /** Governance proof — show binding governance from captured knowledge via resolveTaskStartup. */
169
+ async function showGovernanceProof(vision) {
170
+ try {
171
+ const result = await mcpCall('chain.resolveTaskStartup', { task: vision });
172
+ const governance = result?.bindingGovernance;
173
+ const steering = result?.steeringContext ?? [];
174
+ const allItems = [
175
+ ...(governance?.principles ?? []),
176
+ ...(governance?.standards ?? []),
177
+ ...(governance?.businessRules ?? []),
178
+ ...steering.slice(0, 3),
179
+ ].filter((i) => i.name);
180
+ if (allItems.length > 0) {
181
+ process.stdout.write(`\n ${bold('Your product knowledge is now wired in:')}\n\n`);
182
+ for (const item of allItems.slice(0, 4)) {
183
+ process.stdout.write(` ${dim(icons.dot)} ${item.name}\n`);
184
+ }
185
+ if (allItems.length > 4) {
186
+ process.stdout.write(` ${dim(`...and ${allItems.length - 4} more`)}\n`);
187
+ }
188
+ process.stdout.write('\n');
189
+ }
190
+ }
191
+ catch {
192
+ // Governance proof is best-effort — fall back to orient-based proof
193
+ try {
194
+ const orient = await mcpCall('orient', { brief: true });
195
+ const items = orient?.sections?.flatMap((s) => s.items ?? []).filter((i) => i.name) ?? [];
196
+ if (items.length > 0) {
197
+ process.stdout.write(`\n ${bold("Here's how your product brain will use this:")}\n\n`);
198
+ for (const item of items.slice(0, 5)) {
199
+ process.stdout.write(` ${dim(icons.dot)} ${item.name}\n`);
200
+ }
201
+ process.stdout.write('\n');
202
+ }
203
+ }
204
+ catch {
205
+ // Both proofs failed — skip silently
206
+ }
207
+ }
208
+ }
209
+ /** Deterministic fallback when LLM is unavailable. Dynamic import avoids circular dependency with onboarding.ts. */
210
+ async function runPathBFallback(workspaceName) {
211
+ const { runFallbackOnboarding } = await import('./onboarding.js');
212
+ await runFallbackOnboarding(workspaceName);
213
+ }
214
+ //# sourceMappingURL=onboarding-path-b.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding-path-b.js","sourceRoot":"","sources":["../../src/lib/onboarding-path-b.ts"],"names":[],"mappings":"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"}
@@ -96,7 +96,7 @@ Structure:
96
96
  1. One sentence connecting their problem to what you (PB) do. Use first person.
97
97
  2. One sentence showing you understood something specific they said.
98
98
 
99
- Good example: "I can remember all of that across your AI sessions — so next time you open Claude or Cursor, it already knows about the decision rot problem and your cashflow automation. No more re-explaining."
99
+ Good example: "I can remember all of that across your AI sessions — so next time you open your AI tools, they already know about the decision rot problem and your cashflow automation. No more re-explaining."
100
100
  Bad example: "Product Brain can help — it remembers context. Here's what I'd save: * item 1 * item 2 * item 3"
101
101
 
102
102
  Do NOT list items. Do NOT use bullet points or asterisks. The CLI shows examples separately.
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Shared onboarding utilities — types, extraction mapping, batch capture, retrieval proof.
3
+ * WP-304: Extracted from onboarding.ts to support both Path A and future Path B.
4
+ *
5
+ * DIVERGED from packages/mcp-server/src/tools/start-interview.ts:extractionToBatchEntries per DEC-522.
6
+ * Copy-and-own: CLI uses 120-char truncate limits (vs MCP's 80). Shared package deferred.
7
+ * Duplicated due to monorepo import boundary (BR-108).
8
+ */
9
+ /** @deprecated Use CaptureEntry[] directly — LLM now outputs entry-shaped data. */
10
+ export interface OnboardingExtraction {
11
+ vision: string;
12
+ audience?: string | null;
13
+ techStack?: string[] | null;
14
+ keyTerms?: string[] | null;
15
+ keyDecisions?: string[] | null;
16
+ tensions?: string[] | null;
17
+ }
18
+ /** Result from chain.createEntry. */
19
+ export interface CreateEntryResult {
20
+ entryId: string;
21
+ collection: string;
22
+ name: string;
23
+ status: string;
24
+ }
25
+ /** A single entry to capture. */
26
+ export interface CaptureEntry {
27
+ collection: string;
28
+ name: string;
29
+ description: string;
30
+ typeLabel: string;
31
+ }
32
+ /** Result from the onboarding.chat action — chat mode. */
33
+ export interface OnboardingChatResult {
34
+ content: string;
35
+ /** Coach pattern (Path A): whether the LLM judged the current topic's criteria as met. */
36
+ topicComplete?: boolean;
37
+ /** @deprecated Path B facilitator only. */
38
+ phase?: string;
39
+ signals?: {
40
+ describedProduct?: boolean;
41
+ describedProblem?: boolean;
42
+ answeredWhyPB?: boolean;
43
+ quotableFragments?: string[];
44
+ } | null;
45
+ }
46
+ /** Result from the onboarding.chat action — extract mode. */
47
+ export interface OnboardingExtractResult {
48
+ entries: CaptureEntry[];
49
+ /** @deprecated Backward-compat for Path B. Remove when Path B migrates to entries[]. */
50
+ extraction?: OnboardingExtraction;
51
+ }
52
+ export declare function truncate(str: string, maxLen: number): string;
53
+ export declare function firstNWords(str: string, n: number): string;
54
+ export declare function countWords(text: string): number;
55
+ /**
56
+ * Validate and clean LLM-extracted entries. The LLM outputs entry-shaped data directly;
57
+ * this function validates shape, deduplicates, and caps the result.
58
+ */
59
+ export declare function validateExtractedEntries(entries: unknown[]): CaptureEntry[];
60
+ /** @deprecated Use validateExtractedEntries instead — kept for backward compat during migration. */
61
+ export declare function extractionToEntries(extracted: OnboardingExtraction): CaptureEntry[];
62
+ /**
63
+ * Display one entry example with schema structure.
64
+ * Shows typeLabel (from LLM), name, and description in a clean format.
65
+ */
66
+ export declare function displayEntryExample(entry: CaptureEntry): void;
67
+ /**
68
+ * Batch-capture entries via MCP chain.createEntry.
69
+ * Returns count of captured entries and any error messages.
70
+ */
71
+ export declare function batchCaptureEntries(entries: CaptureEntry[]): Promise<{
72
+ capturedCount: number;
73
+ errors: string[];
74
+ }>;
75
+ /**
76
+ * Show deterministic proof of what was captured — displays the entries that were just saved.
77
+ * Guaranteed to show content (no network call that can fail or return empty).
78
+ * Satisfies BR-141: "First-session flow MUST end with retrieval demonstration."
79
+ */
80
+ export declare function showCapturedSummary(entries: CaptureEntry[], capturedCount: number): void;
81
+ //# sourceMappingURL=onboarding-shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding-shared.d.ts","sourceRoot":"","sources":["../../src/lib/onboarding-shared.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CAC5B;AAED,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,0DAA0D;AAC1D,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE;QACR,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,GAAG,IAAI,CAAC;CACV;AAED,6DAA6D;AAC7D,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,wFAAwF;IACxF,UAAU,CAAC,EAAE,oBAAoB,CAAC;CACnC;AAID,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAMD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,CAmC3E;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,oBAAoB,GAAG,YAAY,EAAE,CA6EnF;AAID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAO7D;AAID;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,YAAY,EAAE,GACtB,OAAO,CAAC;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAoBtD;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAWxF"}