@sonnechasser/ntrp 2.1.11 → 2.2.0

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/index.js CHANGED
@@ -1719,8 +1719,10 @@ var init_prefs = __esm({
1719
1719
  // src/voice/copy.ts
1720
1720
  var copy_exports = {};
1721
1721
  __export(copy_exports, {
1722
+ EXPORT_PICKUP_PHRASE: () => EXPORT_PICKUP_PHRASE,
1722
1723
  voiceAuthFailureAlert: () => voiceAuthFailureAlert,
1723
1724
  voiceAuthFailureHint: () => voiceAuthFailureHint,
1725
+ voiceExportPickupNudge: () => voiceExportPickupNudge,
1724
1726
  voiceGapLoadCta: () => voiceGapLoadCta,
1725
1727
  voiceGapReadyCta: () => voiceGapReadyCta,
1726
1728
  voiceHandoffAddendum: () => voiceHandoffAddendum,
@@ -1873,6 +1875,34 @@ function voiceHealthGloss(status, prefs) {
1873
1875
  }
1874
1876
  });
1875
1877
  }
1878
+ function voiceExportPickupNudge(input, prefs) {
1879
+ const v = voice(prefs);
1880
+ const phrase = EXPORT_PICKUP_PHRASE;
1881
+ if (input.inboxReady) {
1882
+ return pick(v, {
1883
+ robotic: `Open your desktop AI. Tell it to ${phrase}.`,
1884
+ composed: `Open your desktop AI and tell it to ${phrase}.`,
1885
+ casual: `This terminal is not your AI. Open it and tell it to ${phrase}.`,
1886
+ loose: {
1887
+ light: `Written. Open your desktop AI and tell it to ${phrase}.`,
1888
+ medium: `This CLI cannot see your AI. Open it. Tell it to ${phrase}.`,
1889
+ dark: `The file is on disk. Your AI is not in this window. Open it and ${phrase}.`,
1890
+ heavy: `NTRP wrote it. This window is not your AI. Open the desktop app and ${phrase}.`
1891
+ }
1892
+ });
1893
+ }
1894
+ return pick(v, {
1895
+ robotic: `Your desktop AI cannot see this folder. Type /inbox set, then tell that AI to ${phrase}.`,
1896
+ composed: `These files are on disk. Set a pickup folder (/inbox set), then tell your desktop AI to ${phrase}.`,
1897
+ casual: `Your AI cannot see this folder. Type /inbox set, then tell it to ${phrase}.`,
1898
+ loose: {
1899
+ light: `Your AI cannot see this folder yet. Type /inbox set, then tell it to ${phrase}.`,
1900
+ medium: `This folder is invisible to your AI. Type /inbox set, then tell it to ${phrase}.`,
1901
+ dark: `Your AI cannot see this terminal. Type /inbox set, then ${phrase}.`,
1902
+ heavy: `This window is not your AI. Type /inbox set, then ${phrase}.`
1903
+ }
1904
+ });
1905
+ }
1876
1906
  function voiceHandoffAddendum(prefs) {
1877
1907
  const v = voice(prefs);
1878
1908
  return [
@@ -1887,11 +1917,13 @@ function pick(prefs, map) {
1887
1917
  if (typeof entry === "string") return entry;
1888
1918
  return entry[prefs.roast];
1889
1919
  }
1920
+ var EXPORT_PICKUP_PHRASE;
1890
1921
  var init_copy = __esm({
1891
1922
  "src/voice/copy.ts"() {
1892
1923
  "use strict";
1893
1924
  init_catalog();
1894
1925
  init_prefs();
1926
+ EXPORT_PICKUP_PHRASE = "pick up the latest NTRP handoff";
1895
1927
  }
1896
1928
  });
1897
1929
 
@@ -2925,6 +2957,7 @@ __export(handoff_skill_exports, {
2925
2957
  persistHandoffSkillFiles: () => persistHandoffSkillFiles,
2926
2958
  persistStandingSkill: () => persistStandingSkill,
2927
2959
  pickupContextFromEvent: () => pickupContextFromEvent,
2960
+ printExportPickupNudge: () => printExportPickupNudge,
2928
2961
  printHandoffDelivered: () => printHandoffDelivered,
2929
2962
  printStandingSkill: () => printStandingSkill
2930
2963
  });
@@ -3163,11 +3196,14 @@ function maybePrintAiInboxNudge() {
3163
3196
  )
3164
3197
  );
3165
3198
  }
3199
+ function printExportPickupNudge(opts) {
3200
+ console.log(" " + chalk7.dim(voiceExportPickupNudge(opts)));
3201
+ }
3166
3202
  function printHandoffDelivered(event, opts = {}) {
3167
3203
  persistHandoffSkillFiles(event);
3168
3204
  console.log();
3169
3205
  console.log(" " + paint("accent", `Handoff ready (${kindLabel(event.kind)})`));
3170
- maybePrintAiInboxNudge();
3206
+ printExportPickupNudge({ inboxReady: Boolean(event.inbox_path) });
3171
3207
  if (opts.body) {
3172
3208
  console.log(" " + chalk7.dim("File body (--print)"));
3173
3209
  printPlainBlock(opts.body);
@@ -3199,6 +3235,7 @@ var init_handoff_skill = __esm({
3199
3235
  init_store();
3200
3236
  init_theme();
3201
3237
  init_export_kinds();
3238
+ init_copy();
3202
3239
  STANDING_SKILL_NAME = "SKILL.md";
3203
3240
  ARCHIVE_PICKUP_NAME = "pickup.md";
3204
3241
  INBOX_PICKUP_NAME = "latest-pickup.md";
@@ -10723,7 +10760,7 @@ ${strategy.objective}
10723
10760
  ` : "";
10724
10761
  const workstreamSection = strategy.workstreams.length > 0 ? `
10725
10762
  ## Workstreams
10726
- ${strategy.workstreams.map(formatWorkstream).join("\n")}
10763
+ ${strategy.workstreams.map(formatWorkstreamMarkdown).join("\n")}
10727
10764
  ` : "";
10728
10765
  const constraintsSection = filterOperatorLines(strategy.constraints).length > 0 ? `
10729
10766
  ## Constraints
@@ -10779,7 +10816,7 @@ ${strategy.objective}
10779
10816
  ` : "";
10780
10817
  const workstreamSection = strategy.workstreams.length > 0 ? `
10781
10818
  ## Workstreams
10782
- ${strategy.workstreams.map(formatWorkstream).join("\n")}
10819
+ ${strategy.workstreams.map(formatWorkstreamMarkdown).join("\n")}
10783
10820
  ` : "";
10784
10821
  const assumptions = filterOperatorLines(strategy.assumptions);
10785
10822
  const assumptionsSection = assumptions.length > 0 ? `
@@ -10826,7 +10863,7 @@ ${frontmatter}
10826
10863
  ].filter((p) => p != null && String(p).length > 0);
10827
10864
  return parts.join("\n\n") + "\n";
10828
10865
  }
10829
- function formatWorkstream(ws) {
10866
+ function formatWorkstreamMarkdown(ws) {
10830
10867
  const lines = [];
10831
10868
  lines.push(`### ${ws.order}. ${ws.title}`);
10832
10869
  lines.push(`- Problem: ${ws.problem}`);
@@ -12189,6 +12226,7 @@ function resetContextForSwitch(ctx, opts) {
12189
12226
  ctx.thinkState = opts.thinkState;
12190
12227
  ctx.pendingAsk = opts.pendingAsk;
12191
12228
  ctx.lastCraftJobId = opts.lastCraftJobId;
12229
+ ctx.lastStrategyBrief = void 0;
12192
12230
  ctx.gapAudit = void 0;
12193
12231
  ctx.deliverIntent = false;
12194
12232
  ctx.computeInProgress = false;
@@ -14864,6 +14902,8 @@ var init_guide_slides = __esm({
14864
14902
  "",
14865
14903
  "Hit Enter by accident on \u23CE yes? Type b or back \u2014 that rewinds to the focus card. The same word leaves a strategy or think overlay. It does not unload demo data or undo compute; /scratch or a new session is the blunt reset.",
14866
14904
  "",
14905
+ "After a strategy brief, the terminal shows the call, the exams, the next date, and what ships. Type more or expand for the full plan. The library and handoff files already hold every step.",
14906
+ "",
14867
14907
  "Empty dataset? Load a sample with \u23CE use demo data, paste a CSV path, or /ingest. When the gap card says the formulas can compute, \u23CE go ahead runs the local math.",
14868
14908
  "",
14869
14909
  "Vital signs and SaaS metrics compute without an AI key. Every score that has a dollar translation shows it \u2014 that's the point of the stethoscope."
@@ -14872,7 +14912,7 @@ var init_guide_slides = __esm({
14872
14912
  "Power-user slash commands still work. They stay hidden from /help: /new, /diagnose, /metrics, /ingest, /session.",
14873
14913
  '"use demo data" loads a fitted sample book. Company profile is optional. In scripts, /demo --no-profile.',
14874
14914
  'After compute, the prompt returns to \u203A. Brief is the default depth; type "go deep" for the long read.',
14875
- "/home shows phase status. /help lists conversation shortcuts and the Keys legend (\u23CE, b/back, cancel)."
14915
+ "/home shows phase status. /help lists conversation shortcuts and the Keys legend (\u23CE, b/back, more/expand, cancel)."
14876
14916
  ]
14877
14917
  };
14878
14918
  ASK = {
@@ -14918,7 +14958,7 @@ var init_guide_slides = __esm({
14918
14958
  lines: [
14919
14959
  'We think of handoff as a quiet bridge: NTRP writes a board deck or brief into a folder you choose; your desktop AI (Claude, ChatGPT, Cursor, \u2026) opens it. You teach that AI a standing finder once \u2014 then later you just say "pick up the latest NTRP handoff."',
14920
14960
  "",
14921
- '"ship a board deck" or /handoff lands files in ~/Documents/ntrp-inbox by default (/inbox set to change). During demo or company setup \u2014 or anytime \u2014 /inbox skill prints the finder to paste once. After that, each /handoff prints "Handoff ready" without a paste block every write.',
14961
+ '"ship a board deck" or /handoff lands files in ~/Documents/ntrp-inbox by default (/inbox set to change). During demo or company setup \u2014 or anytime \u2014 /inbox skill prints the finder to paste once. After that, each write prints "Handoff ready" without a paste block, then tells you to leave this terminal and pick up the latest NTRP handoff in your desktop AI.',
14922
14962
  "",
14923
14963
  "Skipped earlier? We ask once when you load your own data. Or /inbox set ~/Documents/ntrp-inbox, then /inbox skill. /handoff skill reprints the same finder."
14924
14964
  ],
@@ -14948,6 +14988,8 @@ var init_guide_slides = __esm({
14948
14988
  "",
14949
14989
  "At the confirm card, \u23CE yes builds that plan once. Type keep going to keep working until the plan is ready \u2014 the same armed-Enter pattern as use demo data and go ahead. If you see Best so far, the prompt returns to \u203A and \u23CE keep going continues. Plan ready? Type /strategy review later to check milestones against new vitals.",
14950
14990
  "",
14991
+ "The printed brief is short on purpose: the call, the exams, the next date, and what ships. Type more (or expand) for the full plan. The library and handoff files already hold every step.",
14992
+ "",
14951
14993
  "When a vital is red, /playbook names a matching play \u2014 and outcomes from reviews annotate the catalog with what actually hit here. /remember stores a durable fact; /rate bad <reason> writes a calibration. Optional ~/.ntrp/ANALYST.md is standing voice and priorities (it never overrides safety rules).",
14952
14994
  "",
14953
14995
  "Handy later: /sessions show, /session <id> pickup, /end (transcript + brief), /home, /progress, /help."
@@ -30537,20 +30579,7 @@ function renderCraftHandoffMarkdown(opts) {
30537
30579
  lines.push("## Workstreams");
30538
30580
  lines.push("");
30539
30581
  for (const ws of plan.workstreams) {
30540
- lines.push(`### ${ws.order}. ${ws.title}`);
30541
- lines.push("");
30542
- lines.push(`- Problem: ${ws.problem}`);
30543
- if (ws.rationale && !isGenericWorkstreamRationale(ws.rationale)) {
30544
- lines.push(`- Why this order: ${ws.rationale}`);
30545
- }
30546
- if (ws.actions[0]) lines.push(`- First action (48h): ${ws.actions[0]}`);
30547
- lines.push(`- Effort: ~${Math.round(ws.effort_hours)} team-hours`);
30548
- lines.push(
30549
- `- Exam: ${ws.expected_outcome.metric} ${ws.expected_outcome.baseline} \u2192 ${ws.expected_outcome.target_range} by ${ws.expected_outcome.check_date} (${ws.expected_outcome.measured_by})`
30550
- );
30551
- lines.push(
30552
- `- Contingency: if ${ws.contingency.trigger} (check ${ws.contingency.trigger_check_date}) \u2192 ${ws.contingency.fallback}`
30553
- );
30582
+ lines.push(formatWorkstreamMarkdown(ws).trimEnd());
30554
30583
  lines.push("");
30555
30584
  }
30556
30585
  if (opts.roundtableDigest) {
@@ -30830,93 +30859,183 @@ var init_llm_attribution = __esm({
30830
30859
 
30831
30860
  // src/output/strategy-brief.ts
30832
30861
  import chalk24 from "chalk";
30833
- function printWrapped(text, width, prefix = INDENT, style) {
30862
+ function collectWrapped(lines, text, width, prefix = INDENT, style) {
30834
30863
  for (const line of wrapWords(text, width)) {
30835
- console.log(prefix + (style ? style(line) : line));
30864
+ lines.push(prefix + (style ? style(line) : line));
30836
30865
  }
30837
30866
  }
30838
- function outcomeLine(outcome) {
30839
- return `${chalk24.bold(outcome.metric)}: ${outcome.baseline} ${chalk24.dim("\u2192")} ${chalk24.bold(outcome.target_range)} ${chalk24.dim(`by ${outcome.check_date}`)}`;
30867
+ function outcomeLine(outcome, dateStyle) {
30868
+ const by = dateStyle === "accent" ? paint("accent", `by ${outcome.check_date}`) : chalk24.dim(`by ${outcome.check_date}`);
30869
+ return `${chalk24.bold(outcome.metric)}: ${outcome.baseline} ${chalk24.dim("\u2192")} ${chalk24.bold(outcome.target_range)} ${by}`;
30870
+ }
30871
+ function soonestByDue(items) {
30872
+ if (items.length === 0) return void 0;
30873
+ return [...items].sort((a, b) => a.due.localeCompare(b.due) || 0)[0];
30840
30874
  }
30841
- function printWorkstream(ws, width) {
30842
- console.log(`${INDENT}${paint("accent", `${ws.order}.`)} ${chalk24.bold(ws.title)}`);
30843
- printWrapped(ws.problem, width - 5, INDENT + " ", (s) => chalk24.dim(s));
30844
- console.log(`${INDENT} ${outcomeLine(ws.expected_outcome)}`);
30875
+ function altitudeLine(text) {
30876
+ const sentence = findingHeadline(text) || text.trim();
30877
+ return truncateVisible(sentence, FOH_PROSE_MAX);
30878
+ }
30879
+ function coverageLine(plan, stats) {
30880
+ const totalHours = plan.workstreams.reduce((sum, ws) => sum + ws.effort_hours, 0);
30881
+ const hours = `~${Math.round(totalHours)} total team hours across ${plan.workstreams.length} workstream${plan.workstreams.length === 1 ? "" : "s"}`;
30882
+ if (stats.total_targets <= 0) return chalk24.dim(hours);
30883
+ const coverage = `${stats.measurable_targets} of ${stats.total_targets} targets can be measured with current data`;
30884
+ const coverageStyled = stats.measurable_targets === stats.total_targets ? paint("success", coverage) : chalk24.hex("#eab308")(coverage);
30885
+ return `${coverageStyled}${chalk24.dim(` \xB7 ${hours}`)}`;
30886
+ }
30887
+ function renderFohWorkstream(ws, width) {
30888
+ const lines = [];
30889
+ lines.push(`${INDENT}${paint("accent", `${ws.order}.`)} ${chalk24.bold(ws.title)}`);
30890
+ lines.push(`${INDENT} ${outcomeLine(ws.expected_outcome, "accent")}`);
30891
+ const next = soonestByDue(ws.milestones);
30892
+ if (next) {
30893
+ lines.push(`${INDENT} Next ${paint("accent", next.due)} ${next.label}`);
30894
+ }
30895
+ const ship = soonestByDue(ws.deliverables);
30896
+ if (ship) {
30897
+ lines.push(`${INDENT} Ship ${paint("accent", ship.due)} ${ship.label}`);
30898
+ }
30899
+ lines.push("");
30900
+ return lines;
30901
+ }
30902
+ function renderBohWorkstream(ws, width) {
30903
+ const lines = [];
30904
+ lines.push(`${INDENT}${paint("accent", `${ws.order}.`)} ${chalk24.bold(ws.title)}`);
30905
+ collectWrapped(lines, ws.problem, width - 5, INDENT + " ", (s) => chalk24.dim(s));
30906
+ lines.push(`${INDENT} ${outcomeLine(ws.expected_outcome, "dim")}`);
30845
30907
  for (const li of ws.leading_indicators) {
30846
- console.log(`${INDENT} ${chalk24.dim("Lead:")} ${outcomeLine(li)}`);
30908
+ lines.push(`${INDENT} ${chalk24.dim("Lead:")} ${outcomeLine(li, "dim")}`);
30847
30909
  }
30848
30910
  if (ws.actions.length > 0) {
30849
- console.log(`${INDENT} ${chalk24.dim("First steps")}`);
30911
+ lines.push(`${INDENT} ${chalk24.dim("First steps")}`);
30850
30912
  for (const action of ws.actions.slice(0, 3)) {
30851
- printWrapped(`- ${action}`, width - 7, INDENT + " ", (s) => chalk24.dim(s));
30913
+ collectWrapped(lines, `- ${action}`, width - 7, INDENT + " ", (s) => chalk24.dim(s));
30852
30914
  }
30853
30915
  }
30854
30916
  if (ws.milestones.length > 0) {
30855
- console.log(`${INDENT} ${chalk24.dim("Milestones")}`);
30917
+ lines.push(`${INDENT} ${chalk24.dim("Milestones")}`);
30856
30918
  for (const m of ws.milestones) {
30857
- console.log(`${INDENT} ${paint("accent", m.due)} ${m.label}`);
30919
+ lines.push(`${INDENT} ${paint("accent", m.due)} ${m.label}`);
30858
30920
  }
30859
30921
  }
30860
30922
  if (ws.deliverables.length > 0) {
30861
- console.log(`${INDENT} ${chalk24.dim("Deliverables")}`);
30923
+ lines.push(`${INDENT} ${chalk24.dim("Deliverables")}`);
30862
30924
  for (const d of ws.deliverables) {
30863
- console.log(`${INDENT} ${chalk24.dim("[ ]")} ${d.label} ${chalk24.dim(`due ${d.due}`)}`);
30925
+ lines.push(`${INDENT} ${chalk24.dim("[ ]")} ${d.label} ${chalk24.dim(`due ${d.due}`)}`);
30864
30926
  }
30865
30927
  }
30866
- printWrapped(
30928
+ collectWrapped(
30929
+ lines,
30867
30930
  `If ${ws.contingency.trigger} (check ${ws.contingency.trigger_check_date}), then ${ws.contingency.fallback}`,
30868
30931
  width - 5,
30869
30932
  INDENT + " ",
30870
30933
  (s) => chalk24.dim(s)
30871
30934
  );
30872
- console.log(`${INDENT} ${chalk24.dim(`~${Math.round(ws.effort_hours)} team hours`)}`);
30873
- console.log();
30935
+ lines.push(`${INDENT} ${chalk24.dim(`~${Math.round(ws.effort_hours)} team hours`)}`);
30936
+ lines.push("");
30937
+ return lines;
30938
+ }
30939
+ function renderOperatorList(title, items, width) {
30940
+ const lines = [];
30941
+ if (items.length === 0) return lines;
30942
+ lines.push(`${INDENT}${chalk24.dim(title)}`);
30943
+ for (const item of items) {
30944
+ collectWrapped(lines, `- ${item}`, width - 2, INDENT, (s) => chalk24.dim(s));
30945
+ }
30946
+ lines.push("");
30947
+ return lines;
30874
30948
  }
30875
- function printStrategyBrief(plan, stats) {
30949
+ function renderStrategyBrief(plan, stats, opts = {}) {
30950
+ const mode = opts.mode ?? "foh";
30876
30951
  const width = Math.min(termWidth() - 4, 92);
30877
- console.log();
30878
- console.log(
30952
+ const lines = [""];
30953
+ lines.push(
30879
30954
  `${INDENT}${chalk24.bold(`Strategy brief \u2014 ${plan.title}`)} ${chalk24.dim(`confidence ${plan.confidence.toFixed(2)} \xB7 ${plan.priority} priority \xB7 review ${plan.review_cadence.toLowerCase()}`)}`
30880
30955
  );
30881
- console.log(INDENT + chalk24.dim(hr(width)));
30882
- console.log(`${INDENT}${chalk24.dim("The Call")}`);
30883
- printWrapped(plan.summary_30k, width);
30884
- console.log();
30885
- printWrapped(`Objective: ${plan.objective}`, width, INDENT, (s) => paint("accent", s));
30886
- console.log();
30887
- for (const ws of plan.workstreams) {
30888
- printWorkstream(ws, width);
30889
- }
30890
- const constraints = filterOperatorLines(plan.constraints);
30891
- if (constraints.length > 0) {
30892
- console.log(`${INDENT}${chalk24.dim("Constraints")}`);
30893
- for (const c of constraints) {
30894
- printWrapped(`- ${c}`, width - 2, INDENT, (s) => chalk24.dim(s));
30956
+ if (mode === "foh") {
30957
+ collectWrapped(lines, altitudeLine(plan.summary_30k), width, INDENT);
30958
+ lines.push("");
30959
+ collectWrapped(lines, altitudeLine(plan.objective), width, INDENT, (s) => paint("accent", s));
30960
+ lines.push("");
30961
+ for (const ws of plan.workstreams) {
30962
+ lines.push(...renderFohWorkstream(ws, width));
30895
30963
  }
30896
- console.log();
30897
- }
30898
- const assumptions = filterOperatorLines(plan.assumptions);
30899
- if (assumptions.length > 0) {
30900
- console.log(`${INDENT}${chalk24.dim("Assumptions (not verified, not targets)")}`);
30901
- for (const a of assumptions) {
30902
- printWrapped(`- ${a}`, width - 2, INDENT, (s) => chalk24.dim(s));
30964
+ } else {
30965
+ lines.push(INDENT + chalk24.dim(hr(width)));
30966
+ lines.push(`${INDENT}${chalk24.dim("The Call")}`);
30967
+ collectWrapped(lines, plan.summary_30k, width);
30968
+ lines.push("");
30969
+ collectWrapped(lines, `Objective: ${plan.objective}`, width, INDENT, (s) => paint("accent", s));
30970
+ lines.push("");
30971
+ for (const ws of plan.workstreams) {
30972
+ lines.push(...renderBohWorkstream(ws, width));
30903
30973
  }
30904
- console.log();
30974
+ lines.push(
30975
+ ...renderOperatorList("Constraints", filterOperatorLines(plan.constraints), width)
30976
+ );
30977
+ lines.push(
30978
+ ...renderOperatorList(
30979
+ "Assumptions (not verified, not targets)",
30980
+ filterOperatorLines(plan.assumptions),
30981
+ width
30982
+ )
30983
+ );
30984
+ lines.push(...renderOperatorList("Risks", filterOperatorLines(plan.risks), width));
30905
30985
  }
30906
- const risks = filterOperatorLines(plan.risks);
30907
- if (risks.length > 0) {
30908
- console.log(`${INDENT}${chalk24.dim("Risks")}`);
30909
- for (const r of risks) {
30910
- printWrapped(`- ${r}`, width - 2, INDENT, (s) => chalk24.dim(s));
30911
- }
30912
- console.log();
30986
+ lines.push(INDENT + chalk24.dim(hr(width)));
30987
+ lines.push(`${INDENT}${coverageLine(plan, stats)}`);
30988
+ if (opts.hint) {
30989
+ lines.push(`${INDENT}${chalk24.dim(STRATEGY_BRIEF_EXPAND_HINT)}`);
30913
30990
  }
30914
- const totalHours = plan.workstreams.reduce((sum, ws) => sum + ws.effort_hours, 0);
30915
- console.log(INDENT + chalk24.dim(hr(width)));
30916
- const coverage = stats.total_targets > 0 ? `${stats.measurable_targets} of ${stats.total_targets} targets can be measured with current data` : "No measured targets";
30917
- const coverageStyled = stats.total_targets > 0 && stats.measurable_targets === stats.total_targets ? paint("success", coverage) : chalk24.hex("#eab308")(coverage);
30918
- console.log(`${INDENT}${coverageStyled}${chalk24.dim(` \xB7 ~${Math.round(totalHours)} total team hours across ${plan.workstreams.length} workstream${plan.workstreams.length === 1 ? "" : "s"}`)}`);
30919
- console.log();
30991
+ lines.push("");
30992
+ return lines.join("\n");
30993
+ }
30994
+ function printStrategyBrief(plan, stats, opts = {}) {
30995
+ console.log(renderStrategyBrief(plan, stats, opts));
30996
+ }
30997
+ function resolveStrategyBriefMode(host) {
30998
+ return isVerbose(host.execution) ? "boh" : "foh";
30999
+ }
31000
+ function presentStrategyBrief(host, plan, stats, notices = [], meta = {}) {
31001
+ const mode = resolveStrategyBriefMode(host);
31002
+ printStrategyBrief(plan, stats, { mode, hint: mode === "foh" && !host.oneShot });
31003
+ printStrategyBriefFooter(notices, meta);
31004
+ host.lastStrategyBrief = { plan, stats, notices, meta };
31005
+ }
31006
+ function expandLastStrategyBrief(host) {
31007
+ const last = host.lastStrategyBrief;
31008
+ if (!last) return false;
31009
+ printStrategyBrief(last.plan, last.stats, { mode: "boh", hint: false });
31010
+ printStrategyBriefFooter(last.notices, last.meta);
31011
+ return true;
31012
+ }
31013
+ function isBriefExpandInput(input) {
31014
+ return /^(more|expand)\s*[.!]?\s*$/i.test(input.trim());
31015
+ }
31016
+ function planFromStrategy(strategy) {
31017
+ return {
31018
+ title: strategy.title,
31019
+ objective: strategy.objective || strategy.goal,
31020
+ summary_30k: strategy.raw_excerpt || strategy.goal,
31021
+ hypothesis: strategy.hypothesis,
31022
+ target_segment: strategy.target_segment,
31023
+ priority: strategy.priority,
31024
+ review_cadence: strategy.review_cadence,
31025
+ confidence: strategy.confidence,
31026
+ constraints: strategy.constraints,
31027
+ assumptions: strategy.assumptions,
31028
+ risks: strategy.risks,
31029
+ workstreams: strategy.workstreams
31030
+ };
31031
+ }
31032
+ function statsFromPlan(plan) {
31033
+ let total = 0;
31034
+ for (const ws of plan.workstreams) {
31035
+ total += 1;
31036
+ total += ws.leading_indicators.length;
31037
+ }
31038
+ return { measurable_targets: total, total_targets: total };
30920
31039
  }
30921
31040
  function printStrategyBriefFooter(notices, meta) {
30922
31041
  if (usedGroundedFallback(notices)) {
@@ -30935,7 +31054,10 @@ function printCraftWrapUp(opts) {
30935
31054
  );
30936
31055
  }
30937
31056
  const handoff = opts.inbox_path ?? opts.handoff_path;
30938
- if (handoff) console.log(INDENT + chalk24.dim(handoff));
31057
+ if (handoff) {
31058
+ console.log(INDENT + chalk24.dim(handoff));
31059
+ printExportPickupNudge({ inboxReady: Boolean(opts.inbox_path) });
31060
+ }
30939
31061
  } else {
30940
31062
  console.log(INDENT + paint("accent", "Best so far."));
30941
31063
  const path = opts.library_path ?? opts.handoff_path ?? opts.inbox_path;
@@ -30955,15 +31077,20 @@ function printCraftWrapUp(opts) {
30955
31077
  }
30956
31078
  console.log();
30957
31079
  }
30958
- var INDENT;
31080
+ var STRATEGY_BRIEF_EXPAND_HINT, INDENT, FOH_PROSE_MAX;
30959
31081
  var init_strategy_brief = __esm({
30960
31082
  "src/output/strategy-brief.ts"() {
30961
31083
  "use strict";
30962
31084
  init_theme();
30963
31085
  init_layout();
31086
+ init_formatters();
30964
31087
  init_strategy_signal();
30965
31088
  init_llm_attribution();
31089
+ init_handoff_skill();
31090
+ init_verbosity();
31091
+ STRATEGY_BRIEF_EXPAND_HINT = "Type more to show the full brief.";
30966
31092
  INDENT = " ";
31093
+ FOH_PROSE_MAX = 220;
30967
31094
  }
30968
31095
  });
30969
31096
 
@@ -31324,8 +31451,7 @@ async function runStrategistSession(ctx) {
31324
31451
  console.log();
31325
31452
  return;
31326
31453
  }
31327
- printStrategyBrief(plan, stats);
31328
- printStrategyBriefFooter(notices, meta);
31454
+ presentStrategyBrief(ctx, plan, stats, notices, meta);
31329
31455
  console.log();
31330
31456
  let saved = false;
31331
31457
  if (ctx.rl) {
@@ -31384,14 +31510,14 @@ async function ensureSnapshot(ctx) {
31384
31510
  }
31385
31511
  function printCraftReplResult(ctx, result, objective) {
31386
31512
  if (result.plan) {
31387
- printStrategyBrief(result.plan, {
31513
+ presentStrategyBrief(ctx, result.plan, {
31388
31514
  measurable_targets: result.measurable_targets,
31389
31515
  total_targets: result.total_targets
31390
- });
31516
+ }, result.notices, result.usage);
31391
31517
  } else {
31392
31518
  console.log(" " + chalk25.dim("(No plan produced)"));
31519
+ printStrategyBriefFooter(result.notices, result.usage);
31393
31520
  }
31394
- printStrategyBriefFooter(result.notices, result.usage);
31395
31521
  if (result.library_path) creditStrategySession(ctx);
31396
31522
  printCraftWrapUp({
31397
31523
  status: result.status,
@@ -32001,7 +32127,7 @@ function matchDefinitionExplainer(input) {
32001
32127
  }
32002
32128
  return getMetricExplainer(id);
32003
32129
  }
32004
- function printWrapped2(text, indent = " ") {
32130
+ function printWrapped(text, indent = " ") {
32005
32131
  for (const line of wrapWords(text, 78)) {
32006
32132
  console.log(indent + line);
32007
32133
  }
@@ -32018,10 +32144,10 @@ function tryKeylessDefinitionAnswer(ctx, input) {
32018
32144
  console.log(" " + chalk29.dim(explainer.tagline));
32019
32145
  console.log();
32020
32146
  console.log(" " + bold("Meaning"));
32021
- printWrapped2(explainer.meaning, " ");
32147
+ printWrapped(explainer.meaning, " ");
32022
32148
  console.log();
32023
32149
  console.log(" " + bold("How NTRP calculates it"));
32024
- printWrapped2(explainer.how_computed, " ");
32150
+ printWrapped(explainer.how_computed, " ");
32025
32151
  for (const f of explainer.formula_lines) {
32026
32152
  console.log(" " + paint("accent", f));
32027
32153
  }
@@ -33138,6 +33264,7 @@ var init_smoke_protocol = __esm({
33138
33264
  // src/cli/nl.ts
33139
33265
  var nl_exports = {};
33140
33266
  __export(nl_exports, {
33267
+ runExploreExpandAnswer: () => runExploreExpandAnswer,
33141
33268
  runNaturalLanguage: () => runNaturalLanguage
33142
33269
  });
33143
33270
  import chalk31 from "chalk";
@@ -33145,16 +33272,16 @@ async function runNaturalLanguage(input, ctx) {
33145
33272
  if (isSmokeProtocolTrigger(input)) {
33146
33273
  recordMessage(ctx, "user", input);
33147
33274
  console.log();
33148
- const spinner2 = makeSpinner("Running smoke protocol\u2026");
33275
+ const spinner = makeSpinner("Running smoke protocol\u2026");
33149
33276
  try {
33150
33277
  const result = await runSmokeProtocol(input, ctx);
33151
- spinner2.succeed("Smoke protocol complete");
33278
+ spinner.succeed("Smoke protocol complete");
33152
33279
  printAnswer(result.answer);
33153
33280
  recordMessage(ctx, "agent", result.answer);
33154
33281
  console.log();
33155
33282
  return extractSummary2(result.answer);
33156
33283
  } catch (err) {
33157
- spinner2.fail("Smoke protocol failed");
33284
+ spinner.fail("Smoke protocol failed");
33158
33285
  console.error(" " + chalk31.red(String(err.message ?? err)));
33159
33286
  console.log();
33160
33287
  return;
@@ -33169,6 +33296,22 @@ async function runNaturalLanguage(input, ctx) {
33169
33296
  return;
33170
33297
  }
33171
33298
  recordMessage(ctx, "user", input);
33299
+ const responseMode = resolveExploreResponseMode(input, ctx, ctx.conversation.length);
33300
+ return runExploreAgent(ctx, {
33301
+ userQuestion: input,
33302
+ responseMode,
33303
+ showExpandHint: responseMode === "brief"
33304
+ });
33305
+ }
33306
+ async function runExploreExpandAnswer(ctx, question) {
33307
+ return runExploreAgent(ctx, {
33308
+ userQuestion: question,
33309
+ responseMode: "deep",
33310
+ showExpandHint: false
33311
+ });
33312
+ }
33313
+ async function runExploreAgent(ctx, opts) {
33314
+ const { userQuestion, responseMode, showExpandHint } = opts;
33172
33315
  let snapshot = ctx.snapshot.computeResult;
33173
33316
  if (!snapshot) {
33174
33317
  const metricsFirst = prefersMetricsFirstContext(ctx);
@@ -33185,7 +33328,7 @@ async function runNaturalLanguage(input, ctx) {
33185
33328
  }
33186
33329
  }
33187
33330
  console.log();
33188
- const memoryBlock = await buildMemoryBlock(input).catch((err) => {
33331
+ const memoryBlock = await buildMemoryBlock(userQuestion).catch((err) => {
33189
33332
  debugError("nl.buildMemoryBlock", err);
33190
33333
  return "";
33191
33334
  });
@@ -33196,13 +33339,12 @@ async function runNaturalLanguage(input, ctx) {
33196
33339
  setAgentContext(ctx);
33197
33340
  try {
33198
33341
  const analysisBlock = buildAnalysisBlock(ctx);
33199
- const responseMode = resolveExploreResponseMode(input, ctx, ctx.conversation.length);
33200
33342
  const conversationBlock = getConversationPhaseBlock(ctx, { responseMode });
33201
33343
  const bundle = await loadSessionAnalysisBundle();
33202
33344
  const sessionArtifact = hasAnyAnalysis(bundle) ? buildExploreContextBlock(bundle, ctx) : "";
33203
33345
  for await (const event of agenticFindings(snapshot, ctx.snapshot.divergences, {
33204
33346
  mode: "fresh",
33205
- userQuestion: input,
33347
+ userQuestion,
33206
33348
  sessionContext: ctx.resumedSessionSummary,
33207
33349
  includeMetrics: true,
33208
33350
  analysisBlock,
@@ -33243,7 +33385,7 @@ async function runNaturalLanguage(input, ctx) {
33243
33385
  const { isLlmAuthError: isLlmAuthError2 } = await Promise.resolve().then(() => (init_errors2(), errors_exports2));
33244
33386
  if (isLlmAuthError2(err)) {
33245
33387
  const { queuePendingAsk: queuePendingAsk2 } = await Promise.resolve().then(() => (init_pending_ask(), pending_ask_exports));
33246
- if (!ctx.pendingAsk) queuePendingAsk2(ctx, input, "explore");
33388
+ if (!ctx.pendingAsk) queuePendingAsk2(ctx, userQuestion, "explore");
33247
33389
  const { recoverFromAuthFailure: recoverFromAuthFailure2 } = await Promise.resolve().then(() => (init_auth_recovery(), auth_recovery_exports));
33248
33390
  await recoverFromAuthFailure2(ctx, err);
33249
33391
  return;
@@ -33268,8 +33410,18 @@ async function runNaturalLanguage(input, ctx) {
33268
33410
  saveSessionState(ctx);
33269
33411
  }
33270
33412
  creditNlAnswer(ctx, Math.floor(ctx.messages.length / 2));
33271
- recordAnalysis({ question: input, answer: lastAnswer, tools: toolsUsed, session_id: ctx.sessionId });
33272
- ctx.lastExchange = { question: input, answer: lastAnswer };
33413
+ recordAnalysis({
33414
+ question: userQuestion,
33415
+ answer: lastAnswer,
33416
+ tools: toolsUsed,
33417
+ session_id: ctx.sessionId
33418
+ });
33419
+ ctx.lastExchange = { question: userQuestion, answer: lastAnswer, mode: responseMode };
33420
+ if (showExpandHint) {
33421
+ console.log(
33422
+ " " + chalk31.dim("Type ") + chalk31.cyan("expand") + chalk31.dim(" for more reasoning.")
33423
+ );
33424
+ }
33273
33425
  }
33274
33426
  console.log();
33275
33427
  const { promptQueuedAiStrategist: promptQueuedAiStrategist2 } = await Promise.resolve().then(() => (init_strategist_flow(), strategist_flow_exports));
@@ -36708,6 +36860,7 @@ async function handler10(args, _ctx) {
36708
36860
  if (event.inbox_path) {
36709
36861
  console.log(chalk43.dim(` Inbox: ${event.inbox_path}`));
36710
36862
  }
36863
+ printExportPickupNudge({ inboxReady: Boolean(event.inbox_path) });
36711
36864
  console.log();
36712
36865
  return filepath;
36713
36866
  } catch (err) {
@@ -36724,6 +36877,7 @@ var init_export = __esm({
36724
36877
  init_path_safety();
36725
36878
  init_argparse();
36726
36879
  init_exports_registry();
36880
+ init_handoff_skill();
36727
36881
  init_segments();
36728
36882
  }
36729
36883
  });
@@ -36822,6 +36976,7 @@ async function handler11(args, _ctx) {
36822
36976
  if (event.inbox_path) {
36823
36977
  console.log(chalk44.dim(` Inbox: ${event.inbox_path}`));
36824
36978
  }
36979
+ printExportPickupNudge({ inboxReady: Boolean(event.inbox_path) });
36825
36980
  console.log();
36826
36981
  return folder;
36827
36982
  } catch (err) {
@@ -36839,6 +36994,7 @@ var init_backmeup = __esm({
36839
36994
  init_formatters();
36840
36995
  init_path_safety();
36841
36996
  init_exports_registry();
36997
+ init_handoff_skill();
36842
36998
  EVIDENCE_FILENAMES = {
36843
36999
  freshness: "freshness.csv",
36844
37000
  flow_rate: "flow-rate.csv",
@@ -38423,7 +38579,7 @@ async function handler16(args, ctx) {
38423
38579
  emitResult("strategy", result);
38424
38580
  return;
38425
38581
  }
38426
- renderStrategyResult(result);
38582
+ renderStrategyResult(result, ctx);
38427
38583
  } catch (err) {
38428
38584
  if (isStructuredOutput(ctx.execution)) emitError(first === "craft" ? "strategy.craft" : "strategy", err);
38429
38585
  console.error(chalk50.red(` ${err instanceof Error ? err.message : String(err)}`));
@@ -38579,10 +38735,10 @@ function craftJsonData(result) {
38579
38735
  stop_reason: result.stop_reason ?? null
38580
38736
  };
38581
38737
  }
38582
- function renderStrategyResult(result) {
38738
+ function renderStrategyResult(result, ctx) {
38583
38739
  switch (result.action) {
38584
38740
  case "craft":
38585
- renderCraftResult(result);
38741
+ renderCraftResult(result, ctx);
38586
38742
  return;
38587
38743
  case "review":
38588
38744
  return;
@@ -38598,8 +38754,7 @@ function renderStrategyResult(result) {
38598
38754
  printStrategyList(result.strategies);
38599
38755
  return;
38600
38756
  case "show":
38601
- console.log(chalk50.bold("\n Strategy\n"));
38602
- printStrategyDetail(result.strategy);
38757
+ printStrategyShow(result.strategy, ctx);
38603
38758
  if (result.sources.length > 0) {
38604
38759
  console.log(chalk50.hex("#14b8a6")(" Sources"));
38605
38760
  for (const source of result.sources) {
@@ -38616,17 +38771,17 @@ function renderStrategyResult(result) {
38616
38771
  return;
38617
38772
  }
38618
38773
  }
38619
- function renderCraftResult(result) {
38774
+ function renderCraftResult(result, ctx) {
38620
38775
  if (result.plan) {
38621
- printStrategyBrief(result.plan, {
38776
+ presentStrategyBrief(ctx, result.plan, {
38622
38777
  measurable_targets: result.measurable_targets,
38623
38778
  total_targets: result.total_targets
38624
- });
38779
+ }, result.notices, result.usage);
38625
38780
  } else {
38626
38781
  console.log();
38627
38782
  console.log(" " + chalk50.dim("(No plan produced)"));
38783
+ printStrategyBriefFooter(result.notices, result.usage);
38628
38784
  }
38629
- printStrategyBriefFooter(result.notices, result.usage);
38630
38785
  printCraftWrapUp({
38631
38786
  status: result.status,
38632
38787
  library_path: result.library_path,
@@ -38657,29 +38812,21 @@ function printStrategySummary(strategy) {
38657
38812
  console.log(` ${strategy.goal}`);
38658
38813
  console.log();
38659
38814
  }
38660
- function printStrategyDetail(strategy) {
38661
- printStrategySummary(strategy);
38662
- console.log(chalk50.hex("#14b8a6")(" Hypothesis"));
38663
- console.log(` ${strategy.hypothesis}`);
38664
- console.log();
38665
- console.log(chalk50.hex("#14b8a6")(" Target Segment"));
38666
- console.log(` ${strategy.target_segment}`);
38667
- console.log();
38668
- if (strategy.linked_play_ids.length > 0) {
38669
- console.log(chalk50.hex("#14b8a6")(" Linked Plays"));
38670
- console.log(` ${strategy.linked_play_ids.join(", ")}`);
38671
- console.log();
38672
- }
38673
- if (strategy.success_metrics.length > 0) {
38674
- console.log(chalk50.hex("#14b8a6")(" Success Metrics"));
38675
- for (const metric of strategy.success_metrics) {
38676
- console.log(` - ${metric.name}${metric.target ? `: ${metric.target}` : ""}`);
38815
+ function printStrategyShow(strategy, ctx) {
38816
+ if (strategy.workstreams.length > 0) {
38817
+ const plan = planFromStrategy(strategy);
38818
+ presentStrategyBrief(ctx, plan, statsFromPlan(plan));
38819
+ if (strategy.library_path) {
38820
+ console.log(" " + chalk50.dim(strategy.library_path));
38821
+ console.log();
38677
38822
  }
38823
+ return;
38824
+ }
38825
+ printStrategySummary(strategy);
38826
+ if (strategy.library_path) {
38827
+ console.log(" " + chalk50.dim(strategy.library_path));
38678
38828
  console.log();
38679
38829
  }
38680
- console.log(chalk50.hex("#14b8a6")(" Experiment Design"));
38681
- console.log(` ${strategy.experiment_design}`);
38682
- console.log();
38683
38830
  }
38684
38831
  function statusBadge3(status) {
38685
38832
  switch (status) {
@@ -45854,12 +46001,68 @@ var init_gate2 = __esm({
45854
46001
  }
45855
46002
  });
45856
46003
 
46004
+ // src/conversation/explore-expand.ts
46005
+ import chalk92 from "chalk";
46006
+ function isExploreExpandInput(input) {
46007
+ return /^expand\s*[.!]?\s*$/i.test(input.trim());
46008
+ }
46009
+ function resolveExploreExpand(lastExchange) {
46010
+ const question = lastExchange?.question?.trim();
46011
+ if (!question) return { kind: "ask_first" };
46012
+ if (lastExchange?.mode === "deep") return { kind: "already_deep" };
46013
+ return { kind: "run", question };
46014
+ }
46015
+ async function handleExploreExpand(ctx, line) {
46016
+ const trimmed = line.trim();
46017
+ recordMessage(ctx, "user", trimmed);
46018
+ const decision = resolveExploreExpand(ctx.lastExchange);
46019
+ if (decision.kind === "ask_first") {
46020
+ console.log();
46021
+ console.log(" " + chalk92.dim(EXPLORE_EXPAND_ASK_FIRST));
46022
+ console.log();
46023
+ recordMessage(ctx, "agent", EXPLORE_EXPAND_ASK_FIRST);
46024
+ return EXPLORE_EXPAND_ASK_FIRST;
46025
+ }
46026
+ if (decision.kind === "already_deep") {
46027
+ console.log();
46028
+ console.log(" " + chalk92.dim(EXPLORE_EXPAND_ALREADY_DEEP));
46029
+ console.log();
46030
+ recordMessage(ctx, "agent", EXPLORE_EXPAND_ALREADY_DEEP);
46031
+ return EXPLORE_EXPAND_ALREADY_DEEP;
46032
+ }
46033
+ const runner = expandRunnerForTests;
46034
+ if (!runner && !canUseReplAi(ctx)) {
46035
+ console.log();
46036
+ console.log(
46037
+ " " + chalk92.dim("Type ") + chalk92.cyan("/connect") + chalk92.dim(" to connect a key. Then type expand.")
46038
+ );
46039
+ console.log();
46040
+ recordMessage(ctx, "agent", "Expand needs a key");
46041
+ return "Expand needs a key";
46042
+ }
46043
+ const run2 = runner ?? (await Promise.resolve().then(() => (init_nl(), nl_exports))).runExploreExpandAnswer;
46044
+ const summary = await run2(ctx, decision.question);
46045
+ saveSessionState(ctx);
46046
+ return typeof summary === "string" ? summary : "Expanded answer";
46047
+ }
46048
+ var EXPLORE_EXPAND_ASK_FIRST, EXPLORE_EXPAND_ALREADY_DEEP, expandRunnerForTests;
46049
+ var init_explore_expand = __esm({
46050
+ "src/conversation/explore-expand.ts"() {
46051
+ "use strict";
46052
+ init_repl_api();
46053
+ init_context2();
46054
+ EXPLORE_EXPAND_ASK_FIRST = "Ask a question first.";
46055
+ EXPLORE_EXPAND_ALREADY_DEEP = "Already the long version.";
46056
+ expandRunnerForTests = null;
46057
+ }
46058
+ });
46059
+
45857
46060
  // src/conversation/router.ts
45858
46061
  var router_exports = {};
45859
46062
  __export(router_exports, {
45860
46063
  conversationRouter: () => conversationRouter
45861
46064
  });
45862
- import chalk92 from "chalk";
46065
+ import chalk93 from "chalk";
45863
46066
  function popModalState(ctx) {
45864
46067
  const popped = [];
45865
46068
  if (ctx.strategistState) {
@@ -45892,7 +46095,7 @@ function handleBackNavigation(ctx, line) {
45892
46095
  }
45893
46096
  if (phase === "scope") {
45894
46097
  console.log();
45895
- console.log(" " + chalk92.dim("What should we focus on instead?"));
46098
+ console.log(" " + chalk93.dim("What should we focus on instead?"));
45896
46099
  ctx.scope = void 0;
45897
46100
  clearPendingAsk(ctx);
45898
46101
  saveSessionState(ctx);
@@ -45912,7 +46115,7 @@ function handleBackNavigation(ctx, line) {
45912
46115
  printScopeProposal(ctx);
45913
46116
  if (hadData || hadAnalysis) {
45914
46117
  console.log(
45915
- " " + chalk92.dim(
46118
+ " " + chalk93.dim(
45916
46119
  "Focus gate rewound \u2014 loaded data and any analysis stay. `b` does not unload demo data or undo compute."
45917
46120
  )
45918
46121
  );
@@ -45928,7 +46131,7 @@ function handleBackNavigation(ctx, line) {
45928
46131
  recordMessage(ctx, "user", line);
45929
46132
  recordMessage(ctx, "agent", "Strategy objective adjust (back)");
45930
46133
  console.log();
45931
- console.log(" " + chalk92.dim("What is the objective? State a finish line."));
46134
+ console.log(" " + chalk93.dim("What is the objective? State a finish line."));
45932
46135
  console.log();
45933
46136
  return { handled: true, summary: "Awaiting objective" };
45934
46137
  }
@@ -45940,7 +46143,7 @@ function handleBackNavigation(ctx, line) {
45940
46143
  const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
45941
46144
  console.log();
45942
46145
  console.log(
45943
- " " + chalk92.dim(`Back \u2014 dropped ${popped.join(" and ")}. At `) + chalk92.cyan(backTo) + chalk92.dim(".")
46146
+ " " + chalk93.dim(`Back \u2014 dropped ${popped.join(" and ")}. At `) + chalk93.cyan(backTo) + chalk93.dim(".")
45944
46147
  );
45945
46148
  console.log();
45946
46149
  return { handled: true, summary: "Back" };
@@ -45954,13 +46157,28 @@ function handleBackNavigation(ctx, line) {
45954
46157
  const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
45955
46158
  console.log();
45956
46159
  console.log(
45957
- " " + chalk92.dim(`Back \u2014 dropped ${popped.join(" and ")}. At `) + chalk92.cyan(backTo) + chalk92.dim(".")
46160
+ " " + chalk93.dim(`Back \u2014 dropped ${popped.join(" and ")}. At `) + chalk93.cyan(backTo) + chalk93.dim(".")
45958
46161
  );
45959
46162
  console.log();
45960
46163
  return { handled: true, summary: "Back" };
45961
46164
  }
45962
46165
  return null;
45963
46166
  }
46167
+ function handleBriefExpand(ctx, line) {
46168
+ if (!isBriefExpandInput(line)) return null;
46169
+ if (!ctx.lastStrategyBrief) return null;
46170
+ const phase = resolveConversationPhase(ctx);
46171
+ if (phase === "scope" || phase === "awaiting_data" || phase === "strategize" || phase === "think" || phase === "deliver") {
46172
+ return null;
46173
+ }
46174
+ if (phase === "explore" && isExploreExpandInput(line) && ctx.lastExchange?.question) {
46175
+ return null;
46176
+ }
46177
+ recordMessage(ctx, "user", line);
46178
+ expandLastStrategyBrief(ctx);
46179
+ recordMessage(ctx, "agent", "Full strategy brief");
46180
+ return { handled: true, summary: "Full strategy brief" };
46181
+ }
45964
46182
  async function conversationRouter(input, ctx) {
45965
46183
  if (ctx.oneShot || (ctx.wizardDepth ?? 0) > 0) {
45966
46184
  return { handled: false };
@@ -45983,7 +46201,7 @@ async function conversationRouter(input, ctx) {
45983
46201
  if (!ok) {
45984
46202
  console.log();
45985
46203
  console.log(
45986
- " " + chalk92.dim("Staying on this session. Type ") + chalk92.cyan("/home") + chalk92.dim(" for the dashboard.")
46204
+ " " + chalk93.dim("Staying on this session. Type ") + chalk93.cyan("/home") + chalk93.dim(" for the dashboard.")
45987
46205
  );
45988
46206
  console.log();
45989
46207
  return { handled: true };
@@ -45998,7 +46216,7 @@ async function conversationRouter(input, ctx) {
45998
46216
  }
45999
46217
  console.log();
46000
46218
  console.log(
46001
- " " + chalk92.dim("Start a fresh analysis with ") + chalk92.cyan("/new") + chalk92.dim(" \u2014 or ") + chalk92.cyan("/home") + chalk92.dim(" for the dashboard.")
46219
+ " " + chalk93.dim("Start a fresh analysis with ") + chalk93.cyan("/new") + chalk93.dim(" \u2014 or ") + chalk93.cyan("/home") + chalk93.dim(" for the dashboard.")
46002
46220
  );
46003
46221
  console.log();
46004
46222
  return { handled: true };
@@ -46012,7 +46230,7 @@ async function conversationRouter(input, ctx) {
46012
46230
  const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
46013
46231
  console.log();
46014
46232
  console.log(
46015
- " " + chalk92.dim(`Cancelled \u2014 dropped ${popped.join(" and ")}. Back to `) + chalk92.cyan(backTo) + chalk92.dim(".")
46233
+ " " + chalk93.dim(`Cancelled \u2014 dropped ${popped.join(" and ")}. Back to `) + chalk93.cyan(backTo) + chalk93.dim(".")
46016
46234
  );
46017
46235
  console.log();
46018
46236
  return { handled: true, summary: "Cancelled" };
@@ -46020,6 +46238,8 @@ async function conversationRouter(input, ctx) {
46020
46238
  }
46021
46239
  const backResult = handleBackNavigation(ctx, line);
46022
46240
  if (backResult) return backResult;
46241
+ const expandResult = handleBriefExpand(ctx, line);
46242
+ if (expandResult) return expandResult;
46023
46243
  if (/^\S+$/.test(line) && !/^\d$/.test(line)) {
46024
46244
  const { resolveSessionByToken: resolveSessionByToken2 } = await Promise.resolve().then(() => (init_context2(), context_exports));
46025
46245
  if (resolveSessionByToken2(line, { printErrors: false }) !== void 0) {
@@ -46092,7 +46312,7 @@ async function conversationRouter(input, ctx) {
46092
46312
  }
46093
46313
  if (phase === "compute") {
46094
46314
  console.log();
46095
- console.log(" " + chalk92.dim("Analysis running \u2014 wait for it to finish before typing another question."));
46315
+ console.log(" " + chalk93.dim("Analysis running \u2014 wait for it to finish before typing another question."));
46096
46316
  console.log();
46097
46317
  return { handled: true };
46098
46318
  }
@@ -46105,6 +46325,10 @@ async function conversationRouter(input, ctx) {
46105
46325
  return { handled: true, summary };
46106
46326
  }
46107
46327
  if (phase === "explore") {
46328
+ if (isExploreExpandInput(line)) {
46329
+ const summary = await handleExploreExpand(ctx, line);
46330
+ return { handled: true, summary };
46331
+ }
46108
46332
  if (!canUseReplAi(ctx)) {
46109
46333
  await handleExploreWithoutKey(ctx, line);
46110
46334
  return { handled: true };
@@ -46131,6 +46355,8 @@ var init_router = __esm({
46131
46355
  init_demo();
46132
46356
  init_scope();
46133
46357
  init_pending_ask();
46358
+ init_strategy_brief();
46359
+ init_explore_expand();
46134
46360
  FRESH_START_RE = /\b(start (over|fresh)|new analysis|start again|reset session)\b/i;
46135
46361
  CANCEL_ESCAPE_RE = /^(cancel|stop|abort|quit|never\s?mind|nevermind|forget it)\s*[.!]?\s*$/i;
46136
46362
  }
@@ -46142,7 +46368,7 @@ __export(dispatch_exports, {
46142
46368
  dispatch: () => dispatch,
46143
46369
  replayPendingBlockedLine: () => replayPendingBlockedLine
46144
46370
  });
46145
- import chalk93 from "chalk";
46371
+ import chalk94 from "chalk";
46146
46372
  function printLicenseRequired(command) {
46147
46373
  printLicenseBlocked(command);
46148
46374
  }
@@ -46160,7 +46386,7 @@ async function replayPendingBlockedLine(ctx) {
46160
46386
  if (!hasValidLicense()) return false;
46161
46387
  ctx.pendingBlockedLine = void 0;
46162
46388
  console.log();
46163
- console.log(" " + chalk93.dim("Picking up where you left off\u2026"));
46389
+ console.log(" " + chalk94.dim("Picking up where you left off\u2026"));
46164
46390
  console.log();
46165
46391
  await dispatch(line, ctx);
46166
46392
  return true;
@@ -46230,7 +46456,7 @@ async function dispatch(input, ctx) {
46230
46456
  if (tokens.length === 1) {
46231
46457
  if (/^\d$/.test(first)) {
46232
46458
  console.log(
46233
- " " + chalk93.dim("Looks like a menu pick \u2014 run ") + paint("accent", "/new") + chalk93.dim(" to start (pick Demo, then choose your analysis type).")
46459
+ " " + chalk94.dim("Looks like a menu pick \u2014 run ") + paint("accent", "/new") + chalk94.dim(" to start (pick Demo, then choose your analysis type).")
46234
46460
  );
46235
46461
  return { kind: "handled" };
46236
46462
  }
@@ -46253,19 +46479,19 @@ async function dispatch(input, ctx) {
46253
46479
  return { kind: "handled", summary };
46254
46480
  }
46255
46481
  console.log(
46256
- " " + chalk93.dim("Not in Q&A yet. Confirm the scope, load data, and run analysis first. Type ") + paint("accent", "/home") + chalk93.dim(" for status.")
46482
+ " " + chalk94.dim("Not in Q&A yet. Confirm the scope, load data, and run analysis first. Type ") + paint("accent", "/home") + chalk94.dim(" for status.")
46257
46483
  );
46258
46484
  return { kind: "handled" };
46259
46485
  }
46260
46486
  console.log(
46261
- " " + chalk93.dim("Natural-language questions run inside ntrp. Start with ") + paint("accent", "ntrp") + chalk93.dim(" and type a question after analysis.")
46487
+ " " + chalk94.dim("Natural-language questions run inside ntrp. Start with ") + paint("accent", "ntrp") + chalk94.dim(" and type a question after analysis.")
46262
46488
  );
46263
46489
  return { kind: "handled" };
46264
46490
  }
46265
46491
  async function runSlashCommand(name, args, ctx) {
46266
46492
  const handler53 = await resolveHandler(name);
46267
46493
  if (!handler53) {
46268
- console.error(chalk93.red(` Unknown command: /${name}`));
46494
+ console.error(chalk94.red(` Unknown command: /${name}`));
46269
46495
  return void 0;
46270
46496
  }
46271
46497
  const result = await handler53(args, ctx);
@@ -46302,7 +46528,7 @@ var init_inline_suggestion = __esm({
46302
46528
  });
46303
46529
 
46304
46530
  // src/conversation/loop-guard.ts
46305
- import chalk94 from "chalk";
46531
+ import chalk95 from "chalk";
46306
46532
  function createLoopGuardState() {
46307
46533
  return { phase: null, stuckTurns: 0 };
46308
46534
  }
@@ -46334,10 +46560,10 @@ function printLoopEscalation(phase) {
46334
46560
  if (!guide) return;
46335
46561
  console.log();
46336
46562
  console.log(
46337
- " " + chalk94.yellow("We seem to be going in circles \u2014 you're in ") + paint("accent", guide.mode) + chalk94.yellow(" mode.")
46563
+ " " + chalk95.yellow("We seem to be going in circles \u2014 you're in ") + paint("accent", guide.mode) + chalk95.yellow(" mode.")
46338
46564
  );
46339
- console.log(" " + chalk94.dim("Right now I can only accept: ") + guide.accepts);
46340
- console.log(" " + chalk94.dim("To leave: ") + guide.leave);
46565
+ console.log(" " + chalk95.dim("Right now I can only accept: ") + guide.accepts);
46566
+ console.log(" " + chalk95.dim("To leave: ") + guide.leave);
46341
46567
  console.log();
46342
46568
  }
46343
46569
  var LOOP_GUARD_THRESHOLD, MODAL_PHASES, PHASE_GUIDES;
@@ -46381,7 +46607,7 @@ __export(welcome_exports, {
46381
46607
  resolveWelcomeNextAction: () => resolveWelcomeNextAction,
46382
46608
  staleProcessHomeNotice: () => staleProcessHomeNotice
46383
46609
  });
46384
- import chalk95 from "chalk";
46610
+ import chalk96 from "chalk";
46385
46611
  function formatHomeEntityCounts(counts) {
46386
46612
  const parts = [];
46387
46613
  const people = counts.people ?? 0;
@@ -46395,11 +46621,11 @@ function formatHomeEntityCounts(counts) {
46395
46621
  return parts.join(" \xB7 ");
46396
46622
  }
46397
46623
  function formatEmptyDataHomeHint(savedSessionCount, opts = {}) {
46398
- const onboard = opts.includeOnboard === true ? chalk95.dim(", or ") + paint("accent", "/onboard") + chalk95.dim(" to calibrate") : "";
46624
+ const onboard = opts.includeOnboard === true ? chalk96.dim(", or ") + paint("accent", "/onboard") + chalk96.dim(" to calibrate") : "";
46399
46625
  if (savedSessionCount > 0) {
46400
- return chalk95.dim("Type ") + paint("accent", "use demo data") + chalk95.dim(" to load a sample") + onboard + chalk95.dim(". Type ") + paint("accent", "/session") + chalk95.dim(" to open a saved session");
46626
+ return chalk96.dim("Type ") + paint("accent", "use demo data") + chalk96.dim(" to load a sample") + onboard + chalk96.dim(". Type ") + paint("accent", "/session") + chalk96.dim(" to open a saved session");
46401
46627
  }
46402
- return chalk95.dim("Type ") + paint("accent", "use demo data") + chalk95.dim(" to load a sample pipeline") + onboard;
46628
+ return chalk96.dim("Type ") + paint("accent", "use demo data") + chalk96.dim(" to load a sample pipeline") + onboard;
46403
46629
  }
46404
46630
  function staleProcessHomeNotice() {
46405
46631
  const running = getInstalledVersion();
@@ -46441,19 +46667,19 @@ function sessionSummaryText(s) {
46441
46667
  summary: s.summary,
46442
46668
  dataset: s.dataset
46443
46669
  });
46444
- return summary === NO_SUMMARY ? chalk95.dim(summary) : summary;
46670
+ return summary === NO_SUMMARY ? chalk96.dim(summary) : summary;
46445
46671
  }
46446
46672
  function formatLastSessionLine(s, colW, ctx, opts) {
46447
46673
  const phase = sessionPhaseLabel(s, ctx);
46448
- const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk95.dim(" \xB7 current") : "";
46449
- const meta = `${formatSessionId(s.id, s.name)} ${chalk95.dim("\xB7")} ${chalk95.dim(lensBadgeLabel(s.analysis))} ${chalk95.dim("\xB7")} ${paint("accent", phase)} ${chalk95.dim("\xB7")} ${sessionSummaryText(s)}${current}`;
46674
+ const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk96.dim(" \xB7 current") : "";
46675
+ const meta = `${formatSessionId(s.id, s.name)} ${chalk96.dim("\xB7")} ${chalk96.dim(lensBadgeLabel(s.analysis))} ${chalk96.dim("\xB7")} ${paint("accent", phase)} ${chalk96.dim("\xB7")} ${sessionSummaryText(s)}${current}`;
46450
46676
  return truncateVisible(` ${meta}`, colW);
46451
46677
  }
46452
46678
  function formatActiveSessionLine(s, colW, ctx, opts) {
46453
46679
  const indent = " ";
46454
46680
  const idPart = formatSessionId(s.id, s.name);
46455
- const status = chalk95.dim(` \xB7 ${sessionStatusSuffix(s)}`);
46456
- const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk95.dim(" \xB7 current") : "";
46681
+ const status = chalk96.dim(` \xB7 ${sessionStatusSuffix(s)}`);
46682
+ const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk96.dim(" \xB7 current") : "";
46457
46683
  const suffix = `${status}${current}`;
46458
46684
  const summaryBudget = Math.max(8, colW - visibleWidth(indent) - visibleWidth(idPart) - visibleWidth(suffix) - 2);
46459
46685
  const summaryPart = truncateVisible(sessionSummaryText(s), summaryBudget);
@@ -46494,13 +46720,13 @@ function buildSystemLines(colW, statusRows, recent) {
46494
46720
  lines.push(sectionHeading("System"));
46495
46721
  const labelW = Math.max(...statusRows.map((r) => r.label.length), "last used".length);
46496
46722
  for (const item of statusRows) {
46497
- const label = chalk95.dim(padRight(item.label, labelW));
46723
+ const label = chalk96.dim(padRight(item.label, labelW));
46498
46724
  const state2 = padRight(item.state, 10);
46499
46725
  const detailW = Math.max(1, colW - labelW - 13);
46500
- lines.push(`${label} ${state2} ${chalk95.dim(truncateVisible(item.detail, detailW))}`);
46726
+ lines.push(`${label} ${state2} ${chalk96.dim(truncateVisible(item.detail, detailW))}`);
46501
46727
  }
46502
46728
  if (recent) {
46503
- lines.push(`${chalk95.dim(padRight("last used", labelW))} ${chalk95.dim(recent)}`);
46729
+ lines.push(`${chalk96.dim(padRight("last used", labelW))} ${chalk96.dim(recent)}`);
46504
46730
  }
46505
46731
  return lines;
46506
46732
  }
@@ -46508,10 +46734,10 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
46508
46734
  const lines = [""];
46509
46735
  lines.push(sectionHeading("Last Session"));
46510
46736
  if (!lastSession) {
46511
- lines.push(` ${chalk95.dim("(none)")}`);
46737
+ lines.push(` ${chalk96.dim("(none)")}`);
46512
46738
  lines.push(
46513
46739
  truncateVisible(
46514
- ` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${chalk95.dim(nextAction.label)} ${chalk95.dim(nextAction.detail)}`}`,
46740
+ ` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${chalk96.dim(nextAction.label)} ${chalk96.dim(nextAction.detail)}`}`,
46515
46741
  colW
46516
46742
  )
46517
46743
  );
@@ -46525,7 +46751,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
46525
46751
  if (!isCurrent) {
46526
46752
  lines.push(
46527
46753
  truncateVisible(
46528
- ` ${chalk95.dim("Resume:")} ${paint("accent", `/session ${lastSession.id.slice(-4)}`)}`,
46754
+ ` ${chalk96.dim("Resume:")} ${paint("accent", `/session ${lastSession.id.slice(-4)}`)}`,
46529
46755
  colW
46530
46756
  )
46531
46757
  );
@@ -46534,7 +46760,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
46534
46760
  truncateVisible(` ${actionHint(nextAction.label, nextAction.command, nextAction.detail)}`, colW)
46535
46761
  );
46536
46762
  } else {
46537
- lines.push(truncateVisible(` ${chalk95.dim(nextAction.label)} ${chalk95.dim(nextAction.detail)}`, colW));
46763
+ lines.push(truncateVisible(` ${chalk96.dim(nextAction.label)} ${chalk96.dim(nextAction.detail)}`, colW));
46538
46764
  }
46539
46765
  if (isCurrent && emptyDataHint) {
46540
46766
  lines.push(truncateVisible(` ${emptyDataHint}`, colW));
@@ -46545,14 +46771,14 @@ function buildActiveSessionsLines(colW, ctx, activeSessions) {
46545
46771
  const lines = [""];
46546
46772
  lines.push(sectionHeading("Active Sessions"));
46547
46773
  if (activeSessions.length === 0) {
46548
- lines.push(` ${chalk95.dim("(none in progress)")}`);
46774
+ lines.push(` ${chalk96.dim("(none in progress)")}`);
46549
46775
  return lines;
46550
46776
  }
46551
46777
  for (const s of activeSessions.slice(0, 5)) {
46552
46778
  lines.push(formatActiveSessionLine(s, colW, ctx, { markCurrent: true }));
46553
46779
  }
46554
46780
  if (activeSessions.length > 5) {
46555
- lines.push(` ${chalk95.dim(`+${activeSessions.length - 5} more \xB7 `)}${paint("accent", "/session")}`);
46781
+ lines.push(` ${chalk96.dim(`+${activeSessions.length - 5} more \xB7 `)}${paint("accent", "/session")}`);
46556
46782
  }
46557
46783
  return lines;
46558
46784
  }
@@ -46640,7 +46866,7 @@ async function printWelcome(ctx, version) {
46640
46866
  const gap = Math.max(0, innerW - versionTag.length);
46641
46867
  const gapL = Math.floor(gap / 2);
46642
46868
  push(
46643
- border(`\u256D${"\u2500".repeat(gapL)}`) + chalk95.dim(versionTag) + border(`${"\u2500".repeat(gap - gapL)}\u256E`)
46869
+ border(`\u256D${"\u2500".repeat(gapL)}`) + chalk96.dim(versionTag) + border(`${"\u2500".repeat(gap - gapL)}\u256E`)
46644
46870
  );
46645
46871
  if (useWideLayout) {
46646
46872
  const leftLines = systemLines;
@@ -46667,7 +46893,7 @@ async function printWelcome(ctx, version) {
46667
46893
  push(border(`\u2570${"\u2500".repeat(innerW)}\u256F`));
46668
46894
  push(
46669
46895
  truncateVisible(
46670
- license.valid ? ` ${paint("accent", "/help")}${chalk95.dim(" commands \xB7 ")}${paint("accent", "/deepdive")}${chalk95.dim(" tour \xB7 ")}${paint("accent", "/progress")}${chalk95.dim(" hours \xB7 ")}${paint("accent", "/session")}${chalk95.dim(" resume")}` : ` ${paint("accent", "/help")}${chalk95.dim(" commands \xB7 ")}${paint("accent", "/activate")}${chalk95.dim(" paste a key \xB7 ")}${paint("accent", "/checkout")}${chalk95.dim(" signup \xB7 ")}${paint("accent", "/progress")}${chalk95.dim(" hours")}`,
46896
+ license.valid ? ` ${paint("accent", "/help")}${chalk96.dim(" commands \xB7 ")}${paint("accent", "/deepdive")}${chalk96.dim(" tour \xB7 ")}${paint("accent", "/progress")}${chalk96.dim(" hours \xB7 ")}${paint("accent", "/session")}${chalk96.dim(" resume")}` : ` ${paint("accent", "/help")}${chalk96.dim(" commands \xB7 ")}${paint("accent", "/activate")}${chalk96.dim(" paste a key \xB7 ")}${paint("accent", "/checkout")}${chalk96.dim(" signup \xB7 ")}${paint("accent", "/progress")}${chalk96.dim(" hours")}`,
46671
46897
  cardW
46672
46898
  )
46673
46899
  );
@@ -46678,14 +46904,14 @@ async function printWelcome(ctx, version) {
46678
46904
  if (strategyNudge) {
46679
46905
  push(
46680
46906
  truncateVisible(
46681
- ` ${paint("warning", "\u2691")} ${chalk95.dim(strategyNudge.text)} ${chalk95.dim("\xB7")} ${paint("accent", strategyNudge.command)}`,
46907
+ ` ${paint("warning", "\u2691")} ${chalk96.dim(strategyNudge.text)} ${chalk96.dim("\xB7")} ${paint("accent", strategyNudge.command)}`,
46682
46908
  cardW
46683
46909
  )
46684
46910
  );
46685
46911
  } else if (deepdiveNudge) {
46686
46912
  push(
46687
46913
  truncateVisible(
46688
- ` ${paint("warning", "\u2691")} ${chalk95.dim(deepdiveNudge.text)} ${chalk95.dim("\xB7")} ${paint("accent", deepdiveNudge.command)}`,
46914
+ ` ${paint("warning", "\u2691")} ${chalk96.dim(deepdiveNudge.text)} ${chalk96.dim("\xB7")} ${paint("accent", deepdiveNudge.command)}`,
46689
46915
  cardW
46690
46916
  )
46691
46917
  );
@@ -46693,7 +46919,7 @@ async function printWelcome(ctx, version) {
46693
46919
  } else if (voiceNudge) {
46694
46920
  push(
46695
46921
  truncateVisible(
46696
- ` ${paint("warning", "\u2691")} ${chalk95.dim(voiceNudge.text)} ${chalk95.dim("\xB7")} ${paint("accent", voiceNudge.command)}`,
46922
+ ` ${paint("warning", "\u2691")} ${chalk96.dim(voiceNudge.text)} ${chalk96.dim("\xB7")} ${paint("accent", voiceNudge.command)}`,
46697
46923
  cardW
46698
46924
  )
46699
46925
  );
@@ -46881,7 +47107,7 @@ __export(repl_exports, {
46881
47107
  });
46882
47108
  import { createInterface as createInterface2 } from "readline/promises";
46883
47109
  import { clearLine as clearLine2, cursorTo as cursorTo2 } from "readline";
46884
- import chalk96 from "chalk";
47110
+ import chalk97 from "chalk";
46885
47111
  import { join as join42 } from "path";
46886
47112
  function buildPrompt(ctx) {
46887
47113
  return buildConversationPrompt(ctx);
@@ -46973,12 +47199,12 @@ function renderInlineSuggestion(rl, prompt, ctx) {
46973
47199
  suggestionPainted = suffix !== null;
46974
47200
  clearLine2(process.stdout, 0);
46975
47201
  cursorTo2(process.stdout, 0);
46976
- process.stdout.write(prompt + line + (suffix ? chalk96.dim(suffix) : ""));
47202
+ process.stdout.write(prompt + line + (suffix ? chalk97.dim(suffix) : ""));
46977
47203
  cursorTo2(process.stdout, promptWidth + cursor);
46978
47204
  }
46979
47205
  function appendTurnLine(current, promptLabel, currentSummary) {
46980
- const currentLine = currentSummary ? `${promptLabel} ${current} ${chalk96.white("\u2192")} ${currentSummary}` : `${promptLabel} ${current}`;
46981
- console.log(" " + chalk96.dim(currentLine));
47206
+ const currentLine = currentSummary ? `${promptLabel} ${current} ${chalk97.white("\u2192")} ${currentSummary}` : `${promptLabel} ${current}`;
47207
+ console.log(" " + chalk97.dim(currentLine));
46982
47208
  console.log();
46983
47209
  }
46984
47210
  async function goHome(ctx, version, history, opts) {
@@ -46988,7 +47214,7 @@ async function goHome(ctx, version, history, opts) {
46988
47214
  clearTerminalHome();
46989
47215
  if (opts?.banner) {
46990
47216
  console.log();
46991
- console.log(" " + paint("accent", "\u2713") + " " + chalk96.dim(opts.banner));
47217
+ console.log(" " + paint("accent", "\u2713") + " " + chalk97.dim(opts.banner));
46992
47218
  }
46993
47219
  await printWelcome(ctx, version);
46994
47220
  }
@@ -47011,11 +47237,11 @@ async function handleDispatchResult(result, ctx, version, history) {
47011
47237
  case "unknown":
47012
47238
  if (result.suggestion) {
47013
47239
  console.log(
47014
- " " + chalk96.red(`Unknown command: ${result.token}.`) + chalk96.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk96.dim("?")
47240
+ " " + chalk97.red(`Unknown command: ${result.token}.`) + chalk97.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk97.dim("?")
47015
47241
  );
47016
47242
  } else {
47017
47243
  console.log(
47018
- " " + chalk96.red(`Unknown command: ${result.token}`) + chalk96.dim(" Type ") + paint("accent", "/help") + chalk96.dim(" to see available commands.")
47244
+ " " + chalk97.red(`Unknown command: ${result.token}`) + chalk97.dim(" Type ") + paint("accent", "/help") + chalk97.dim(" to see available commands.")
47019
47245
  );
47020
47246
  }
47021
47247
  break;
@@ -47039,7 +47265,7 @@ async function runRepl(ctx, version) {
47039
47265
  });
47040
47266
  ctx.rl = rl;
47041
47267
  console.log();
47042
- console.log(" " + chalk96.dim("What do you want to look at?"));
47268
+ console.log(" " + chalk97.dim("What do you want to look at?"));
47043
47269
  console.log();
47044
47270
  if (ctx.pendingUpdateCheck) {
47045
47271
  void ctx.pendingUpdateCheck.then((result) => {
@@ -47081,7 +47307,7 @@ async function runRepl(ctx, version) {
47081
47307
  return;
47082
47308
  }
47083
47309
  sigintPrimed = true;
47084
- console.log("\n " + chalk96.dim("Type /exit to quit, or press Ctrl+C again."));
47310
+ console.log("\n " + chalk97.dim("Type /exit to quit, or press Ctrl+C again."));
47085
47311
  };
47086
47312
  rl.on("SIGINT", sigintHandler);
47087
47313
  function shutdownRepl() {
@@ -47118,7 +47344,7 @@ async function runRepl(ctx, version) {
47118
47344
  if (!typed && !enterAction) {
47119
47345
  clearGhostRowAfterSubmit();
47120
47346
  const coach = consumeOrientEmptyEnterCoach(ctx);
47121
- if (coach) console.log(" " + chalk96.dim(coach));
47347
+ if (coach) console.log(" " + chalk97.dim(coach));
47122
47348
  continue;
47123
47349
  }
47124
47350
  const line = typed || enterAction.submit;
@@ -47169,11 +47395,11 @@ async function runRepl(ctx, version) {
47169
47395
  ctx.wizardDepth = 0;
47170
47396
  ctx.secretInputActive = false;
47171
47397
  if (err instanceof Error && err.message === "Cancelled") {
47172
- console.log(" " + chalk96.dim("Cancelled."));
47398
+ console.log(" " + chalk97.dim("Cancelled."));
47173
47399
  } else {
47174
47400
  const { tryRecoverLlmAuthFailure: tryRecoverLlmAuthFailure2 } = await Promise.resolve().then(() => (init_auth_recovery(), auth_recovery_exports));
47175
47401
  if (!await tryRecoverLlmAuthFailure2(ctx, err)) {
47176
- console.error(" " + chalk96.red("Error: " + String(err.message ?? err)));
47402
+ console.error(" " + chalk97.red("Error: " + String(err.message ?? err)));
47177
47403
  }
47178
47404
  }
47179
47405
  }
@@ -47200,10 +47426,10 @@ async function runRepl(ctx, version) {
47200
47426
  await closeSession(ctx);
47201
47427
  }
47202
47428
  if (isTranscriptActive(ctx.sessionId)) {
47203
- console.log(" " + chalk96.dim("Transcript: ") + chalk96.dim(transcriptPathForSession(ctx.sessionId)));
47204
- console.log(" " + chalk96.dim("Context brief: ") + chalk96.dim(contextDocPathForSession(ctx.sessionId)));
47429
+ console.log(" " + chalk97.dim("Transcript: ") + chalk97.dim(transcriptPathForSession(ctx.sessionId)));
47430
+ console.log(" " + chalk97.dim("Context brief: ") + chalk97.dim(contextDocPathForSession(ctx.sessionId)));
47205
47431
  }
47206
- console.log(" " + chalk96.dim(randomGoodbye()));
47432
+ console.log(" " + chalk97.dim(randomGoodbye()));
47207
47433
  }
47208
47434
  function printHelpOneShot() {
47209
47435
  printHelp();
@@ -47211,35 +47437,43 @@ function printHelpOneShot() {
47211
47437
  function printHelp() {
47212
47438
  console.log();
47213
47439
  console.log(" " + sectionHeading("Conversation"));
47214
- console.log(" " + chalk96.dim("Type the question. You do not need a slash command."));
47215
- console.log(" " + chalk96.dim("Paste a CSV path or type ") + paint("accent", '"use demo data"') + chalk96.dim(" to load data."));
47216
- console.log(" " + chalk96.dim("After analysis, type questions in English."));
47217
- console.log(" " + chalk96.dim("Type ") + paint("accent", '"how should we fix this?"') + chalk96.dim(" to make a strategy. Type ") + paint("accent", "keep going") + chalk96.dim(" at confirm to keep working until the plan is ready."));
47218
- console.log(" " + chalk96.dim("Type ") + paint("accent", '"ship a board deck"') + chalk96.dim(" to write a handoff."));
47219
- console.log(" " + chalk96.dim("The ") + paint("accent", "\u203A") + chalk96.dim(" prompt shows brief or deep after analysis. Brief is the default."));
47440
+ console.log(" " + chalk97.dim("Type the question. You do not need a slash command."));
47441
+ console.log(" " + chalk97.dim("Paste a CSV path or type ") + paint("accent", '"use demo data"') + chalk97.dim(" to load data."));
47442
+ console.log(" " + chalk97.dim("After analysis, type questions in English."));
47443
+ console.log(" " + chalk97.dim("Type ") + paint("accent", '"how should we fix this?"') + chalk97.dim(" to make a strategy. Type ") + paint("accent", "keep going") + chalk97.dim(" at confirm to keep working until the plan is ready."));
47444
+ console.log(" " + chalk97.dim("Type ") + paint("accent", '"ship a board deck"') + chalk97.dim(" to write a handoff."));
47445
+ console.log(" " + chalk97.dim("The ") + paint("accent", "\u203A") + chalk97.dim(" prompt shows brief or deep after analysis. Brief is the default."));
47220
47446
  console.log();
47221
47447
  console.log(" " + sectionHeading("Keys"));
47222
47448
  console.log(
47223
- " " + paint("accent", "\u23CE") + chalk96.dim(
47449
+ " " + paint("accent", "\u23CE") + chalk97.dim(
47224
47450
  " Accepts the default. At the main prompt it runs the armed action (yes, use demo data, go ahead, /connect, /update, keep going)."
47225
47451
  )
47226
47452
  );
47227
47453
  console.log(
47228
- " " + chalk96.dim(
47454
+ " " + chalk97.dim(
47229
47455
  " On yes/no questions and menus it accepts yes (or the recommended option). Type something else to decline or pick another path."
47230
47456
  )
47231
47457
  );
47232
47458
  console.log(
47233
- " " + paint("accent", "b") + chalk96.dim(" / ") + paint("accent", "back") + chalk96.dim(" Steps back one confirm gate, or leaves a modal. Does not unload data or undo compute.")
47459
+ " " + paint("accent", "b") + chalk97.dim(" / ") + paint("accent", "back") + chalk97.dim(" Steps back one confirm gate, or leaves a modal. Does not unload data or undo compute.")
47460
+ );
47461
+ console.log(
47462
+ " " + chalk97.dim("On ") + paint("accent", "/settings") + chalk97.dim(" menus, ") + paint("accent", "b") + chalk97.dim(" leaves the hub (same as Done).")
47234
47463
  );
47235
47464
  console.log(
47236
- " " + chalk96.dim("On ") + paint("accent", "/settings") + chalk96.dim(" menus, ") + paint("accent", "b") + chalk96.dim(" leaves the hub (same as Done).")
47465
+ " " + paint("accent", "more") + chalk97.dim(" Shows the full strategy brief after the short summary.")
47237
47466
  );
47238
47467
  console.log(
47239
- " " + paint("accent", "cancel") + chalk96.dim(" Drops the current modal overlay (strategy, think, ship, unconfirmed scope).")
47468
+ " " + paint("accent", "expand") + chalk97.dim(
47469
+ " After a short Q&A answer, shows more reasoning for that same answer. With no last answer, expands the strategy brief when one is on screen."
47470
+ )
47240
47471
  );
47241
47472
  console.log(
47242
- " " + chalk96.dim("On ") + paint("accent", "/deepdive") + chalk96.dim(" slides, ") + paint("accent", "b") + chalk96.dim(" moves to the previous slide.")
47473
+ " " + paint("accent", "cancel") + chalk97.dim(" Drops the current modal overlay (strategy, think, ship, unconfirmed scope).")
47474
+ );
47475
+ console.log(
47476
+ " " + chalk97.dim("On ") + paint("accent", "/deepdive") + chalk97.dim(" slides, ") + paint("accent", "b") + chalk97.dim(" moves to the previous slide.")
47243
47477
  );
47244
47478
  console.log();
47245
47479
  console.log(" " + sectionHeading("Shortcuts"));
@@ -47267,11 +47501,11 @@ function printHelp() {
47267
47501
  ];
47268
47502
  const maxW = Math.max(...shortcuts.map(([c]) => c.length)) + 2;
47269
47503
  for (const [cmd, desc] of shortcuts) {
47270
- console.log(` ${paint("accent", padRight(cmd, maxW))} ${chalk96.dim(desc)}`);
47504
+ console.log(` ${paint("accent", padRight(cmd, maxW))} ${chalk97.dim(desc)}`);
47271
47505
  }
47272
47506
  console.log();
47273
47507
  console.log(" " + sectionHeading("Teach NTRP"));
47274
- console.log(" " + chalk96.dim("NTRP learns your business over time. There are three ways to teach it:"));
47508
+ console.log(" " + chalk97.dim("NTRP learns your business over time. There are three ways to teach it:"));
47275
47509
  const teach = [
47276
47510
  ["/remember <fact>", "Store a fact, a decision, or a preference"],
47277
47511
  ["/recall [topic]", "Show what NTRP stores about your business"],
@@ -47280,13 +47514,13 @@ function printHelp() {
47280
47514
  ];
47281
47515
  const teachMaxW = Math.max(...teach.map(([c]) => c.length)) + 2;
47282
47516
  for (const [cmd, desc] of teach) {
47283
- console.log(` ${paint("accent", padRight(cmd, teachMaxW))} ${chalk96.dim(desc)}`);
47517
+ console.log(` ${paint("accent", padRight(cmd, teachMaxW))} ${chalk97.dim(desc)}`);
47284
47518
  }
47285
- console.log(" " + chalk96.dim("When a key is connected, NTRP stores a small number of facts when you close a session."));
47519
+ console.log(" " + chalk97.dim("When a key is connected, NTRP stores a small number of facts when you close a session."));
47286
47520
  console.log();
47287
- console.log(" " + chalk96.dim("Factory reset: type ") + paint("accent", "/scratch") + chalk96.dim("."));
47521
+ console.log(" " + chalk97.dim("Factory reset: type ") + paint("accent", "/scratch") + chalk97.dim("."));
47288
47522
  console.log();
47289
- console.log(" " + chalk96.dim("These commands also work: ") + paint("accent", "/new") + chalk96.dim(", ") + paint("accent", "/diagnose") + chalk96.dim(", ") + paint("accent", "/metrics") + chalk96.dim(", ") + paint("accent", "/session") + chalk96.dim("."));
47523
+ console.log(" " + chalk97.dim("These commands also work: ") + paint("accent", "/new") + chalk97.dim(", ") + paint("accent", "/diagnose") + chalk97.dim(", ") + paint("accent", "/metrics") + chalk97.dim(", ") + paint("accent", "/session") + chalk97.dim("."));
47290
47524
  console.log();
47291
47525
  }
47292
47526
  var REPL_BUILTINS, ANSI_PATTERN, GOODBYES, GHOST_HINTS, ghostHintTurn, activeGhostHint, suggestionPainted;
@@ -47386,7 +47620,7 @@ init_errors();
47386
47620
  init_diagnostics();
47387
47621
  init_types();
47388
47622
  init_version();
47389
- import chalk97 from "chalk";
47623
+ import chalk98 from "chalk";
47390
47624
  var VERSION = getInstalledVersion();
47391
47625
  function exitIfVersionFlag(argv) {
47392
47626
  const rest = argv.slice(2).filter((a) => a === "--version" || a === "-v");
@@ -47424,7 +47658,7 @@ async function main() {
47424
47658
  debug: args.globals.debug
47425
47659
  });
47426
47660
  if (!ctx.execution.color) {
47427
- chalk97.level = 0;
47661
+ chalk98.level = 0;
47428
47662
  }
47429
47663
  fatalReporting = {
47430
47664
  command: firstToken(args.input) || "ntrp",
@@ -47441,16 +47675,16 @@ async function main() {
47441
47675
  if (isStructuredOutput(ctx.execution)) {
47442
47676
  emitError(cmd || "ntrp", new NtrpError("license_invalid", lic.message, 3 /* Auth */));
47443
47677
  }
47444
- console.error(chalk97.red(`
47678
+ console.error(chalk98.red(`
47445
47679
  ${lic.message}`));
47446
- console.error(chalk97.dim(" Trial's over \u2014 /upgrade and paste your key.\n"));
47680
+ console.error(chalk98.dim(" Trial's over \u2014 /upgrade and paste your key.\n"));
47447
47681
  process.exit(1);
47448
47682
  }
47449
47683
  }
47450
47684
  const PROFILE_HINT_SKIP = /* @__PURE__ */ new Set(["onboard", "setup", "config", "connect", "activate", "help", "home", "exit", "quit", "clear", "profile", "progress", "deepdive", "settings", "voice", "logs"]);
47451
47685
  if (!isProfileConfigured() && !PROFILE_HINT_SKIP.has(cmd) && !ctx.execution.quiet) {
47452
47686
  console.error(
47453
- " " + chalk97.dim("Tip: run ") + paint("accent", "ntrp") + chalk97.dim(" interactively to set up your company profile for richer answers.")
47687
+ " " + chalk98.dim("Tip: run ") + paint("accent", "ntrp") + chalk98.dim(" interactively to set up your company profile for richer answers.")
47454
47688
  );
47455
47689
  }
47456
47690
  const result = await dispatch(args.input, ctx);
@@ -47462,12 +47696,12 @@ async function main() {
47462
47696
  }
47463
47697
  if (result.suggestion) {
47464
47698
  console.error(
47465
- chalk97.red(` Unknown command: ${result.token}.`) + chalk97.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk97.dim("?")
47699
+ chalk98.red(` Unknown command: ${result.token}.`) + chalk98.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk98.dim("?")
47466
47700
  );
47467
47701
  } else {
47468
- console.error(chalk97.red(` Unknown command: ${result.token}`));
47702
+ console.error(chalk98.red(` Unknown command: ${result.token}`));
47469
47703
  }
47470
- console.error(chalk97.dim(" Run 'ntrp' for the interactive prompt."));
47704
+ console.error(chalk98.dim(" Run 'ntrp' for the interactive prompt."));
47471
47705
  process.exit(1);
47472
47706
  break;
47473
47707
  case "help":
@@ -47520,7 +47754,7 @@ async function main() {
47520
47754
  if (justUpdated) {
47521
47755
  clearTerminalHome();
47522
47756
  console.log();
47523
- console.log(" " + paint("accent", "\u2713") + " " + chalk97.dim(`Now running v${justUpdated.to}`));
47757
+ console.log(" " + paint("accent", "\u2713") + " " + chalk98.dim(`Now running v${justUpdated.to}`));
47524
47758
  }
47525
47759
  await printWelcome2(ctx, VERSION);
47526
47760
  await runRepl(ctx, VERSION);
@@ -47534,9 +47768,9 @@ async function die(err, scope) {
47534
47768
  if (fatalReporting.structured) {
47535
47769
  emitError(fatalReporting.command, err);
47536
47770
  }
47537
- console.error(chalk97.red(` ${describeError(err)}`));
47771
+ console.error(chalk98.red(` ${describeError(err)}`));
47538
47772
  if (!(err instanceof NtrpError) && err instanceof Error && err.stack) {
47539
- console.error(chalk97.dim(err.stack.split("\n").slice(1).join("\n")));
47773
+ console.error(chalk98.dim(err.stack.split("\n").slice(1).join("\n")));
47540
47774
  }
47541
47775
  process.exit(err instanceof NtrpError ? err.exitCode : 1 /* RuntimeError */);
47542
47776
  }