@sonnechasser/ntrp 1.4.8 → 1.4.9
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 +138 -25
- package/dist/mcp/server.js +28 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12330,7 +12330,7 @@ var init_guide_slides = __esm({
|
|
|
12330
12330
|
tagline: "Start with the question you care about \u2014 we'll mirror it back before we compute.",
|
|
12331
12331
|
visual: {
|
|
12332
12332
|
kind: "funnel",
|
|
12333
|
-
caption: "When a dim \u23CE hint shows, bare Enter submits it. No hint means Enter does nothing.",
|
|
12333
|
+
caption: "When a dim \u23CE hint shows, bare Enter submits it. Type b (or back) to step back one gate. No hint means Enter does nothing.",
|
|
12334
12334
|
funnel: [
|
|
12335
12335
|
{ label: "Type a question", widthPct: 100 },
|
|
12336
12336
|
{ label: "\u23CE yes (scope)", widthPct: 78 },
|
|
@@ -12341,6 +12341,8 @@ var init_guide_slides = __esm({
|
|
|
12341
12341
|
lines: [
|
|
12342
12342
|
`We designed the conversation so you don't need a slash to start. Type the question you actually need \u2014 "is our retention real for the board?" or "pipeline health" \u2014 and NTRP restates it as a scope card so you can confirm we're answering the right thing.`,
|
|
12343
12343
|
"",
|
|
12344
|
+
"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.",
|
|
12345
|
+
"",
|
|
12344
12346
|
"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.",
|
|
12345
12347
|
"",
|
|
12346
12348
|
"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."
|
|
@@ -12349,7 +12351,7 @@ var init_guide_slides = __esm({
|
|
|
12349
12351
|
"Power-user slash commands still work. They stay hidden from /help: /new, /diagnose, /metrics, /ingest, /session.",
|
|
12350
12352
|
'"use demo data" loads a fitted sample book. Company profile is optional. In scripts, /demo --no-profile.',
|
|
12351
12353
|
'After compute, the prompt returns to \u203A. Brief is the default depth; type "go deep" for the long read.',
|
|
12352
|
-
"/home shows phase status. /help lists conversation shortcuts \
|
|
12354
|
+
"/home shows phase status. /help lists conversation shortcuts and the Keys legend (\u23CE, b/back, cancel)."
|
|
12353
12355
|
]
|
|
12354
12356
|
};
|
|
12355
12357
|
ASK = {
|
|
@@ -12369,7 +12371,7 @@ var init_guide_slides = __esm({
|
|
|
12369
12371
|
"",
|
|
12370
12372
|
'"what is our ARR?" or "why is this red?" need a loaded dataset. Narrative findings and /ask need a stored key \u2014 /connect pastes any provider key and we detect it.',
|
|
12371
12373
|
"",
|
|
12372
|
-
"Replay this tour with /deepdive, jump to one slide with /deepdive freshness (or nrr, arr, \u2026), or /deepdive guide for this how-to section. When the prompt shows a dim \u23CE hint (yes, use demo data, go ahead, /connect), bare Enter submits it."
|
|
12374
|
+
"Replay this tour with /deepdive, jump to one slide with /deepdive freshness (or nrr, arr, \u2026), or /deepdive guide for this how-to section. When the prompt shows a dim \u23CE hint (yes, use demo data, go ahead, /connect), bare Enter submits it \u2014 and b / back steps back one confirm gate (or the previous tour slide while you're in /deepdive)."
|
|
12373
12375
|
],
|
|
12374
12376
|
deepdive: [
|
|
12375
12377
|
"/connect ollama for a keyless local model. /connect --base-url <url> --id <name> for any OpenAI-compatible endpoint.",
|
|
@@ -12597,7 +12599,9 @@ function paintIntro(opts) {
|
|
|
12597
12599
|
extraLines: [
|
|
12598
12600
|
...TOUR_INTRO_LINES,
|
|
12599
12601
|
"",
|
|
12600
|
-
chalk10.dim(
|
|
12602
|
+
chalk10.dim(
|
|
12603
|
+
"No AI key needed for this tour. Enter advances; b goes to the previous slide; /deepdive (or d) opens more on any slide. After the tour, b / back steps back one confirm gate in the REPL."
|
|
12604
|
+
)
|
|
12601
12605
|
],
|
|
12602
12606
|
footer: `${progressDots(opts.index, opts.total)} \u23CE next \xB7 q skip`
|
|
12603
12607
|
});
|
|
@@ -12796,7 +12800,7 @@ async function offerFirstRunTour(ctx) {
|
|
|
12796
12800
|
{
|
|
12797
12801
|
value: "tour",
|
|
12798
12802
|
label: "Take the tour",
|
|
12799
|
-
description: "\u23CE
|
|
12803
|
+
description: "\u23CE next \xB7 b back on slides \u2014 /deepdive on any slide for more"
|
|
12800
12804
|
},
|
|
12801
12805
|
{
|
|
12802
12806
|
value: "skip",
|
|
@@ -12862,7 +12866,7 @@ var init_metric_tour = __esm({
|
|
|
12862
12866
|
"",
|
|
12863
12867
|
"We're a stethoscope, not a hospital: we listen hard, translate scores into dollars, and point at plays \u2014 you decide the surgery."
|
|
12864
12868
|
];
|
|
12865
|
-
TOUR_OFFER_BLURB = "How we think about SaaS numbers and five vitals \u2014 then how to talk to NTRP and ship work to your AI.";
|
|
12869
|
+
TOUR_OFFER_BLURB = "How we think about SaaS numbers and five vitals \u2014 then how to talk to NTRP and ship work to your AI. On slides, b goes back; after the tour, the same word steps back at confirm gates.";
|
|
12866
12870
|
}
|
|
12867
12871
|
});
|
|
12868
12872
|
|
|
@@ -15593,7 +15597,8 @@ function buildConversationPrompt(ctx) {
|
|
|
15593
15597
|
const enterHint2 = action ? chalk11.dim(` \xB7 \u23CE ${action.hint}`) : "";
|
|
15594
15598
|
return accentPromptHead(phase, sessionName) + chalk11.dim(stack) + enterHint2 + " ";
|
|
15595
15599
|
}
|
|
15596
|
-
const
|
|
15600
|
+
const modalBack = phase === "scope" || phase === "awaiting_data" || phase === "strategize" ? " \xB7 b back" : "";
|
|
15601
|
+
const enterHint = action ? chalk11.dim(`\u23CE ${action.hint}${modalBack} `) : "";
|
|
15597
15602
|
return accentPromptHead(phase, sessionName) + enterHint;
|
|
15598
15603
|
}
|
|
15599
15604
|
var PROMPT_LABELS;
|
|
@@ -21813,10 +21818,12 @@ var init_agent_context = __esm({
|
|
|
21813
21818
|
var scope_exports = {};
|
|
21814
21819
|
__export(scope_exports, {
|
|
21815
21820
|
confirmScope: () => confirmScope,
|
|
21821
|
+
isBackInput: () => isBackInput,
|
|
21816
21822
|
isScopeAdjustInput: () => isScopeAdjustInput,
|
|
21817
21823
|
isScopeConfirmInput: () => isScopeConfirmInput,
|
|
21818
21824
|
isSkipClarifier: () => isSkipClarifier,
|
|
21819
|
-
proposeScopeFromIntent: () => proposeScopeFromIntent
|
|
21825
|
+
proposeScopeFromIntent: () => proposeScopeFromIntent,
|
|
21826
|
+
unconfirmScope: () => unconfirmScope
|
|
21820
21827
|
});
|
|
21821
21828
|
function proposeScopeFromIntent(input) {
|
|
21822
21829
|
const text = input.trim();
|
|
@@ -21861,12 +21868,20 @@ function confirmScope(ctx) {
|
|
|
21861
21868
|
if (ctx.scope.primary_lens === "revenue_metrics" || ctx.scope.primary_lens === "gtm_health") {
|
|
21862
21869
|
}
|
|
21863
21870
|
}
|
|
21871
|
+
function unconfirmScope(ctx) {
|
|
21872
|
+
if (!ctx.scope?.confirmed_at) return;
|
|
21873
|
+
const { confirmed_at: _dropped, ...rest } = ctx.scope;
|
|
21874
|
+
ctx.scope = rest;
|
|
21875
|
+
}
|
|
21864
21876
|
function isScopeConfirmInput(input) {
|
|
21865
21877
|
return /^(yes|y|yeah|yep|correct|looks good|that'?s right|confirm|ok|okay|go)$/i.test(input.trim());
|
|
21866
21878
|
}
|
|
21867
21879
|
function isScopeAdjustInput(input) {
|
|
21868
21880
|
return /^(adjust|change|refine|edit|no|nope)$/i.test(input.trim());
|
|
21869
21881
|
}
|
|
21882
|
+
function isBackInput(input) {
|
|
21883
|
+
return /^(b|back|prev)\s*[.!]?\s*$/i.test(input.trim());
|
|
21884
|
+
}
|
|
21870
21885
|
function isSkipClarifier(input) {
|
|
21871
21886
|
return /^skip$/i.test(input.trim());
|
|
21872
21887
|
}
|
|
@@ -23300,7 +23315,7 @@ function buildSituationalAwarenessBlock(ctx, opts = {}) {
|
|
|
23300
23315
|
`Phase: ${phase} (${formatPhaseLabel(phase)}) \u2014 ${PHASE_MEANING[phase]}`
|
|
23301
23316
|
];
|
|
23302
23317
|
if (channel === "think") {
|
|
23303
|
-
lines.push("Channel: think \u2014 socratic partner; type done/cancel returns to \u203A");
|
|
23318
|
+
lines.push("Channel: think \u2014 socratic partner; type done/cancel/b back returns to \u203A");
|
|
23304
23319
|
lines.push("Response mode: deep (tools on)");
|
|
23305
23320
|
} else if (channel === "strategist") {
|
|
23306
23321
|
lines.push("Channel: strategist \u2014 measurable plan engine owns sequencing");
|
|
@@ -23344,11 +23359,13 @@ function buildSituationalAwarenessBlock(ctx, opts = {}) {
|
|
|
23344
23359
|
} else if (phase === "awaiting_data") {
|
|
23345
23360
|
lines.push("Already done: scope confirmed; analysis not ready");
|
|
23346
23361
|
lines.push(
|
|
23347
|
-
'Available now: tell the user to paste a CSV path, type "use demo data",
|
|
23362
|
+
'Available now: tell the user to paste a CSV path, type "use demo data", \u23CE go ahead when can_compute, or b/back to rewind the focus card \u2014 you cannot open files'
|
|
23348
23363
|
);
|
|
23349
23364
|
} else if (phase === "scope") {
|
|
23350
23365
|
lines.push("Already done: intent proposed; waiting on confirm");
|
|
23351
|
-
lines.push(
|
|
23366
|
+
lines.push(
|
|
23367
|
+
"Available now: wait for CLI confirm (\u23CE yes) or b/back/adjust \u2014 do not invent a different question"
|
|
23368
|
+
);
|
|
23352
23369
|
} else if (phase === "orient") {
|
|
23353
23370
|
lines.push("Already done: nothing locked yet");
|
|
23354
23371
|
lines.push("Available now: help the user name a focus; CLI will propose scope from their words");
|
|
@@ -23421,13 +23438,13 @@ var init_situation = __esm({
|
|
|
23421
23438
|
FUNNEL_SPINE = "Funnel: orient \u2192 scope \u2192 data \u2192 compute \u2192 explore | side doors: think, strategy, ship";
|
|
23422
23439
|
PHASE_MEANING = {
|
|
23423
23440
|
orient: "setup \u2014 open chat; user has not locked a scope yet",
|
|
23424
|
-
scope: "scope confirm \u2014 CLI owns yes/adjust; do not re-propose unless asked",
|
|
23425
|
-
awaiting_data: "data gate \u2014 load CSV/demo or compute; CLI owns the gate",
|
|
23441
|
+
scope: "scope confirm \u2014 CLI owns yes / b back / adjust; do not re-propose unless asked",
|
|
23442
|
+
awaiting_data: "data gate \u2014 load CSV/demo or compute; b/back rewinds to scope confirm (does not unload data); CLI owns the gate",
|
|
23426
23443
|
compute: "compute in progress \u2014 wait",
|
|
23427
23444
|
explore: "analysis complete \u2014 free-form Q&A on this session's artifact",
|
|
23428
|
-
think: "socratic think channel \u2014 return to \u203A via done/cancel",
|
|
23429
|
-
strategize: "strategist flow \u2014 objective confirm or plan drafting",
|
|
23430
|
-
deliver: "ship/handoff wizard \u2014 CLI owns write confirms"
|
|
23445
|
+
think: "socratic think channel \u2014 return to \u203A via done/cancel/b back",
|
|
23446
|
+
strategize: "strategist flow \u2014 objective confirm (yes / b back / adjust) or plan drafting",
|
|
23447
|
+
deliver: "ship/handoff wizard \u2014 CLI owns write confirms; b/back or cancel leaves the draft"
|
|
23431
23448
|
};
|
|
23432
23449
|
}
|
|
23433
23450
|
});
|
|
@@ -29957,7 +29974,7 @@ async function handleStrategizeFlow(input, ctx) {
|
|
|
29957
29974
|
" " + chalk37.dim("That looks like a question. A strategy objective is waiting.")
|
|
29958
29975
|
);
|
|
29959
29976
|
console.log(
|
|
29960
|
-
" " + chalk37.dim("Type ") + chalk37.cyan("yes") + chalk37.dim(" to make the plan. Type ") + chalk37.cyan("adjust") + chalk37.dim(" to change the objective. Type ") + chalk37.cyan("cancel") + chalk37.dim(" to answer questions first.")
|
|
29977
|
+
" " + chalk37.dim("Type ") + chalk37.cyan("yes") + chalk37.dim(" to make the plan. Type ") + chalk37.cyan("b") + chalk37.dim(" / ") + chalk37.cyan("adjust") + chalk37.dim(" to change the objective. Type ") + chalk37.cyan("cancel") + chalk37.dim(" to answer questions first.")
|
|
29961
29978
|
);
|
|
29962
29979
|
console.log();
|
|
29963
29980
|
return "Awaiting confirm";
|
|
@@ -29970,7 +29987,7 @@ async function handleStrategizeFlow(input, ctx) {
|
|
|
29970
29987
|
}
|
|
29971
29988
|
console.log();
|
|
29972
29989
|
console.log(
|
|
29973
|
-
" " + chalk37.dim("Type ") + chalk37.cyan("yes") + chalk37.dim(" to make the plan. Type ") + chalk37.cyan("adjust") + chalk37.dim(" to change the objective. Type ") + chalk37.cyan("cancel") + chalk37.dim(" to stop.")
|
|
29990
|
+
" " + chalk37.dim("Type ") + chalk37.cyan("yes") + chalk37.dim(" to make the plan. Type ") + chalk37.cyan("b") + chalk37.dim(" / ") + chalk37.cyan("adjust") + chalk37.dim(" to change the objective. Type ") + chalk37.cyan("cancel") + chalk37.dim(" to stop.")
|
|
29974
29991
|
);
|
|
29975
29992
|
console.log();
|
|
29976
29993
|
return "Awaiting confirm";
|
|
@@ -30147,7 +30164,7 @@ function printObjectiveCard(ctx, objective, proposed) {
|
|
|
30147
30164
|
);
|
|
30148
30165
|
console.log();
|
|
30149
30166
|
console.log(
|
|
30150
|
-
" " + chalk37.dim("Confirm? ") + chalk37.cyan("\u23CE yes") + chalk37.dim(" \xB7 ") + chalk37.cyan("adjust") + chalk37.dim(" \xB7 ") + chalk37.cyan("cancel")
|
|
30167
|
+
" " + chalk37.dim("Confirm? ") + chalk37.cyan("\u23CE yes") + chalk37.dim(" \xB7 ") + chalk37.cyan("b back") + chalk37.dim(" \xB7 ") + chalk37.cyan("adjust") + chalk37.dim(" \xB7 ") + chalk37.cyan("cancel")
|
|
30151
30168
|
);
|
|
30152
30169
|
console.log();
|
|
30153
30170
|
}
|
|
@@ -32515,7 +32532,7 @@ function printScopeProposal(ctx) {
|
|
|
32515
32532
|
}
|
|
32516
32533
|
console.log();
|
|
32517
32534
|
console.log(
|
|
32518
|
-
" " + chalk52.dim("Confirm? ") + chalk52.cyan("\u23CE yes") + chalk52.dim(" \xB7 ") + chalk52.cyan("adjust")
|
|
32535
|
+
" " + chalk52.dim("Confirm? ") + chalk52.cyan("\u23CE yes") + chalk52.dim(" \xB7 ") + chalk52.cyan("b back") + chalk52.dim(" \xB7 ") + chalk52.cyan("adjust")
|
|
32519
32536
|
);
|
|
32520
32537
|
console.log();
|
|
32521
32538
|
}
|
|
@@ -37032,6 +37049,7 @@ CLI slide deck: SaaS refresher, five vital signs (definition, formula, visual, d
|
|
|
37032
37049
|
Bare \`/deepdive\` runs the full onboarding tour. Type \`/deepdive guide\` to jump to how to use NTRP (includes teaching the inbox once).
|
|
37033
37050
|
Type \`/deepdive handoff\` for the ship-to-AI slide. Type \`/deepdive <metric>\` to jump to one metric card.
|
|
37034
37051
|
Type \`/deepdive list\` to print the catalog. Works without an AI key. Re-run anytime from the homescreen.
|
|
37052
|
+
During the tour: Enter advances, \`b\` / \`back\` goes to the previous slide, \`q\` quits. After the tour, the same \`b\` / \`back\` word steps back one confirm gate in the REPL (scope, data, strategy) \u2014 it does not unload data or undo compute.
|
|
37035
37053
|
Live values overlay when an analysis exists.`
|
|
37036
37054
|
},
|
|
37037
37055
|
{
|
|
@@ -37046,7 +37064,7 @@ handler: ../commands/thinkwithme.ts
|
|
|
37046
37064
|
|
|
37047
37065
|
Open a dedicated \`think \u203A\` channel to explore ideas, challenge assumptions, and pull evidence from your data.
|
|
37048
37066
|
Bare \`/thinkwithme\` enters the channel. Type \`/thinkwithme <topic>\` to seed the first turn.
|
|
37049
|
-
Requires an analysis and an AI key (\`/connect\`). Type \`done\` or \`
|
|
37067
|
+
Requires an analysis and an AI key (\`/connect\`). Type \`done\`, \`cancel\`, or \`b\` / \`back\` to return to \u203A.
|
|
37050
37068
|
When you are ready to commit to a plan, say so or the partner can hand off to \`/strategy\`.`
|
|
37051
37069
|
},
|
|
37052
37070
|
{
|
|
@@ -38792,6 +38810,83 @@ function popModalState(ctx) {
|
|
|
38792
38810
|
}
|
|
38793
38811
|
return popped;
|
|
38794
38812
|
}
|
|
38813
|
+
function handleBackNavigation(ctx, line) {
|
|
38814
|
+
if (!isBackInput(line)) return null;
|
|
38815
|
+
const phase = resolveConversationPhase(ctx);
|
|
38816
|
+
if (phase === "orient" || phase === "explore" || phase === "compute") {
|
|
38817
|
+
return null;
|
|
38818
|
+
}
|
|
38819
|
+
if (phase === "scope") {
|
|
38820
|
+
console.log();
|
|
38821
|
+
console.log(" " + chalk84.dim("What should we focus on instead?"));
|
|
38822
|
+
ctx.scope = void 0;
|
|
38823
|
+
clearPendingAsk(ctx);
|
|
38824
|
+
saveSessionState(ctx);
|
|
38825
|
+
recordMessage(ctx, "user", line);
|
|
38826
|
+
recordMessage(ctx, "agent", "Scope cleared (back)");
|
|
38827
|
+
console.log();
|
|
38828
|
+
return { handled: true, summary: "Scope cleared" };
|
|
38829
|
+
}
|
|
38830
|
+
if (phase === "awaiting_data") {
|
|
38831
|
+
if (!ctx.scope?.confirmed_at) return null;
|
|
38832
|
+
const hadData = sessionHasData(ctx);
|
|
38833
|
+
const hadAnalysis = ctx.stage === "analyzed" || isAnalysisReady(ctx);
|
|
38834
|
+
unconfirmScope(ctx);
|
|
38835
|
+
saveSessionState(ctx);
|
|
38836
|
+
recordMessage(ctx, "user", line);
|
|
38837
|
+
recordMessage(ctx, "agent", "Scope unconfirmed (back)");
|
|
38838
|
+
printScopeProposal(ctx);
|
|
38839
|
+
if (hadData || hadAnalysis) {
|
|
38840
|
+
console.log(
|
|
38841
|
+
" " + chalk84.dim(
|
|
38842
|
+
"Focus gate rewound \u2014 loaded data and any analysis stay. `b` does not unload demo data or undo compute."
|
|
38843
|
+
)
|
|
38844
|
+
);
|
|
38845
|
+
console.log();
|
|
38846
|
+
}
|
|
38847
|
+
return { handled: true, summary: "Scope unconfirmed" };
|
|
38848
|
+
}
|
|
38849
|
+
if (phase === "strategize") {
|
|
38850
|
+
const state2 = ctx.strategistState;
|
|
38851
|
+
if (state2?.step === "objective_confirm") {
|
|
38852
|
+
state2.step = "objective_input";
|
|
38853
|
+
saveSessionState(ctx);
|
|
38854
|
+
recordMessage(ctx, "user", line);
|
|
38855
|
+
recordMessage(ctx, "agent", "Strategy objective adjust (back)");
|
|
38856
|
+
console.log();
|
|
38857
|
+
console.log(" " + chalk84.dim("What is the objective? State a finish line."));
|
|
38858
|
+
console.log();
|
|
38859
|
+
return { handled: true, summary: "Awaiting objective" };
|
|
38860
|
+
}
|
|
38861
|
+
const popped = popModalState(ctx);
|
|
38862
|
+
if (popped.length === 0) return null;
|
|
38863
|
+
saveSessionState(ctx);
|
|
38864
|
+
recordMessage(ctx, "user", line);
|
|
38865
|
+
recordMessage(ctx, "agent", `Back \u2014 dropped ${popped.join(", ")}`);
|
|
38866
|
+
const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
|
|
38867
|
+
console.log();
|
|
38868
|
+
console.log(
|
|
38869
|
+
" " + chalk84.dim(`Back \u2014 dropped ${popped.join(" and ")}. At `) + chalk84.cyan(backTo) + chalk84.dim(".")
|
|
38870
|
+
);
|
|
38871
|
+
console.log();
|
|
38872
|
+
return { handled: true, summary: "Back" };
|
|
38873
|
+
}
|
|
38874
|
+
if (phase === "think" || phase === "deliver") {
|
|
38875
|
+
const popped = popModalState(ctx);
|
|
38876
|
+
if (popped.length === 0) return null;
|
|
38877
|
+
saveSessionState(ctx);
|
|
38878
|
+
recordMessage(ctx, "user", line);
|
|
38879
|
+
recordMessage(ctx, "agent", `Back \u2014 dropped ${popped.join(", ")}`);
|
|
38880
|
+
const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
|
|
38881
|
+
console.log();
|
|
38882
|
+
console.log(
|
|
38883
|
+
" " + chalk84.dim(`Back \u2014 dropped ${popped.join(" and ")}. At `) + chalk84.cyan(backTo) + chalk84.dim(".")
|
|
38884
|
+
);
|
|
38885
|
+
console.log();
|
|
38886
|
+
return { handled: true, summary: "Back" };
|
|
38887
|
+
}
|
|
38888
|
+
return null;
|
|
38889
|
+
}
|
|
38795
38890
|
async function conversationRouter(input, ctx) {
|
|
38796
38891
|
if (ctx.oneShot || (ctx.wizardDepth ?? 0) > 0) {
|
|
38797
38892
|
return { handled: false };
|
|
@@ -38821,6 +38916,8 @@ async function conversationRouter(input, ctx) {
|
|
|
38821
38916
|
return { handled: true, summary: "Cancelled" };
|
|
38822
38917
|
}
|
|
38823
38918
|
}
|
|
38919
|
+
const backResult = handleBackNavigation(ctx, line);
|
|
38920
|
+
if (backResult) return backResult;
|
|
38824
38921
|
if (/^\S+$/.test(line) && !/^\d$/.test(line)) {
|
|
38825
38922
|
const { resolveSessionByToken: resolveSessionByToken2 } = await Promise.resolve().then(() => (init_context2(), context_exports));
|
|
38826
38923
|
if (resolveSessionByToken2(line, { printErrors: false }) !== void 0) {
|
|
@@ -38925,6 +39022,8 @@ var init_router = __esm({
|
|
|
38925
39022
|
init_think_flow();
|
|
38926
39023
|
init_context2();
|
|
38927
39024
|
init_demo();
|
|
39025
|
+
init_scope();
|
|
39026
|
+
init_pending_ask();
|
|
38928
39027
|
FRESH_START_RE = /\b(start (over|fresh)|new analysis|start again|reset session)\b/i;
|
|
38929
39028
|
CANCEL_ESCAPE_RE = /^(cancel|stop|abort|quit|never\s?mind|nevermind|forget it)\s*[.!]?\s*$/i;
|
|
38930
39029
|
}
|
|
@@ -39148,17 +39247,17 @@ var init_loop_guard2 = __esm({
|
|
|
39148
39247
|
PHASE_GUIDES = {
|
|
39149
39248
|
scope: {
|
|
39150
39249
|
mode: "scope confirmation",
|
|
39151
|
-
accepts: "\u23CE or yes (run with this focus) \xB7 adjust (restate it) \xB7 a new focus statement",
|
|
39152
|
-
leave: "cancel drops the proposal \xB7 /home shows the dashboard"
|
|
39250
|
+
accepts: "\u23CE or yes (run with this focus) \xB7 b / back (clear it) \xB7 adjust (restate it) \xB7 a new focus statement",
|
|
39251
|
+
leave: "b / back or cancel drops the proposal \xB7 /home shows the dashboard"
|
|
39153
39252
|
},
|
|
39154
39253
|
awaiting_data: {
|
|
39155
39254
|
mode: "data loading",
|
|
39156
39255
|
accepts: 'a CSV path \xB7 "use demo data" \xB7 "go ahead" (compute once data is loaded) \xB7 \u23CE runs the action shown at the prompt',
|
|
39157
|
-
leave: "
|
|
39256
|
+
leave: "b / back rewinds to the focus confirm card (data stays) \xB7 cancel \xB7 /home shows the dashboard"
|
|
39158
39257
|
},
|
|
39159
39258
|
strategize: {
|
|
39160
39259
|
mode: "strategy objective confirm",
|
|
39161
|
-
accepts: "\u23CE or yes (build the plan) \xB7 adjust (restate the objective) \xB7 cancel",
|
|
39260
|
+
accepts: "\u23CE or yes (build the plan) \xB7 b / back or adjust (restate the objective) \xB7 cancel",
|
|
39162
39261
|
leave: "cancel drops the strategy session and returns to Q&A"
|
|
39163
39262
|
}
|
|
39164
39263
|
};
|
|
@@ -40086,6 +40185,20 @@ function printHelp() {
|
|
|
40086
40185
|
console.log(" " + chalk88.dim("Type ") + paint("accent", '"ship a board deck"') + chalk88.dim(" to write a handoff."));
|
|
40087
40186
|
console.log(" " + chalk88.dim("The ") + paint("accent", "\u203A") + chalk88.dim(" prompt shows brief or deep after analysis. Brief is the default."));
|
|
40088
40187
|
console.log();
|
|
40188
|
+
console.log(" " + sectionHeading("Keys"));
|
|
40189
|
+
console.log(
|
|
40190
|
+
" " + paint("accent", "\u23CE") + chalk88.dim(" Runs the armed action shown at the prompt (yes, use demo data, go ahead, /connect).")
|
|
40191
|
+
);
|
|
40192
|
+
console.log(
|
|
40193
|
+
" " + paint("accent", "b") + chalk88.dim(" / ") + paint("accent", "back") + chalk88.dim(" Steps back one confirm gate, or leaves a modal. Does not unload data or undo compute.")
|
|
40194
|
+
);
|
|
40195
|
+
console.log(
|
|
40196
|
+
" " + paint("accent", "cancel") + chalk88.dim(" Drops the current modal overlay (strategy, think, ship, unconfirmed scope).")
|
|
40197
|
+
);
|
|
40198
|
+
console.log(
|
|
40199
|
+
" " + chalk88.dim("On ") + paint("accent", "/deepdive") + chalk88.dim(" slides, ") + paint("accent", "b") + chalk88.dim(" moves to the previous slide.")
|
|
40200
|
+
);
|
|
40201
|
+
console.log();
|
|
40089
40202
|
console.log(" " + sectionHeading("Shortcuts"));
|
|
40090
40203
|
const shortcuts = [
|
|
40091
40204
|
["/home", "Show status"],
|
package/dist/mcp/server.js
CHANGED
|
@@ -10317,6 +10317,7 @@ CLI slide deck: SaaS refresher, five vital signs (definition, formula, visual, d
|
|
|
10317
10317
|
Bare \`/deepdive\` runs the full onboarding tour. Type \`/deepdive guide\` to jump to how to use NTRP (includes teaching the inbox once).
|
|
10318
10318
|
Type \`/deepdive handoff\` for the ship-to-AI slide. Type \`/deepdive <metric>\` to jump to one metric card.
|
|
10319
10319
|
Type \`/deepdive list\` to print the catalog. Works without an AI key. Re-run anytime from the homescreen.
|
|
10320
|
+
During the tour: Enter advances, \`b\` / \`back\` goes to the previous slide, \`q\` quits. After the tour, the same \`b\` / \`back\` word steps back one confirm gate in the REPL (scope, data, strategy) \u2014 it does not unload data or undo compute.
|
|
10320
10321
|
Live values overlay when an analysis exists.`
|
|
10321
10322
|
},
|
|
10322
10323
|
{
|
|
@@ -10331,7 +10332,7 @@ handler: ../commands/thinkwithme.ts
|
|
|
10331
10332
|
|
|
10332
10333
|
Open a dedicated \`think \u203A\` channel to explore ideas, challenge assumptions, and pull evidence from your data.
|
|
10333
10334
|
Bare \`/thinkwithme\` enters the channel. Type \`/thinkwithme <topic>\` to seed the first turn.
|
|
10334
|
-
Requires an analysis and an AI key (\`/connect\`). Type \`done\` or \`
|
|
10335
|
+
Requires an analysis and an AI key (\`/connect\`). Type \`done\`, \`cancel\`, or \`b\` / \`back\` to return to \u203A.
|
|
10335
10336
|
When you are ready to commit to a plan, say so or the partner can hand off to \`/strategy\`.`
|
|
10336
10337
|
},
|
|
10337
10338
|
{
|
|
@@ -13242,10 +13243,12 @@ var init_agent_context = __esm({
|
|
|
13242
13243
|
var scope_exports = {};
|
|
13243
13244
|
__export(scope_exports, {
|
|
13244
13245
|
confirmScope: () => confirmScope,
|
|
13246
|
+
isBackInput: () => isBackInput,
|
|
13245
13247
|
isScopeAdjustInput: () => isScopeAdjustInput,
|
|
13246
13248
|
isScopeConfirmInput: () => isScopeConfirmInput,
|
|
13247
13249
|
isSkipClarifier: () => isSkipClarifier,
|
|
13248
|
-
proposeScopeFromIntent: () => proposeScopeFromIntent
|
|
13250
|
+
proposeScopeFromIntent: () => proposeScopeFromIntent,
|
|
13251
|
+
unconfirmScope: () => unconfirmScope
|
|
13249
13252
|
});
|
|
13250
13253
|
function proposeScopeFromIntent(input) {
|
|
13251
13254
|
const text = input.trim();
|
|
@@ -13290,12 +13293,20 @@ function confirmScope(ctx) {
|
|
|
13290
13293
|
if (ctx.scope.primary_lens === "revenue_metrics" || ctx.scope.primary_lens === "gtm_health") {
|
|
13291
13294
|
}
|
|
13292
13295
|
}
|
|
13296
|
+
function unconfirmScope(ctx) {
|
|
13297
|
+
if (!ctx.scope?.confirmed_at) return;
|
|
13298
|
+
const { confirmed_at: _dropped, ...rest } = ctx.scope;
|
|
13299
|
+
ctx.scope = rest;
|
|
13300
|
+
}
|
|
13293
13301
|
function isScopeConfirmInput(input) {
|
|
13294
13302
|
return /^(yes|y|yeah|yep|correct|looks good|that'?s right|confirm|ok|okay|go)$/i.test(input.trim());
|
|
13295
13303
|
}
|
|
13296
13304
|
function isScopeAdjustInput(input) {
|
|
13297
13305
|
return /^(adjust|change|refine|edit|no|nope)$/i.test(input.trim());
|
|
13298
13306
|
}
|
|
13307
|
+
function isBackInput(input) {
|
|
13308
|
+
return /^(b|back|prev)\s*[.!]?\s*$/i.test(input.trim());
|
|
13309
|
+
}
|
|
13299
13310
|
function isSkipClarifier(input) {
|
|
13300
13311
|
return /^skip$/i.test(input.trim());
|
|
13301
13312
|
}
|
|
@@ -14246,7 +14257,8 @@ function buildConversationPrompt(ctx) {
|
|
|
14246
14257
|
const enterHint2 = action ? chalk8.dim(` \xB7 \u23CE ${action.hint}`) : "";
|
|
14247
14258
|
return accentPromptHead(phase, sessionName) + chalk8.dim(stack) + enterHint2 + " ";
|
|
14248
14259
|
}
|
|
14249
|
-
const
|
|
14260
|
+
const modalBack = phase === "scope" || phase === "awaiting_data" || phase === "strategize" ? " \xB7 b back" : "";
|
|
14261
|
+
const enterHint = action ? chalk8.dim(`\u23CE ${action.hint}${modalBack} `) : "";
|
|
14250
14262
|
return accentPromptHead(phase, sessionName) + enterHint;
|
|
14251
14263
|
}
|
|
14252
14264
|
var PROMPT_LABELS;
|
|
@@ -18837,7 +18849,7 @@ async function handleStrategizeFlow(input, ctx) {
|
|
|
18837
18849
|
" " + chalk17.dim("That looks like a question. A strategy objective is waiting.")
|
|
18838
18850
|
);
|
|
18839
18851
|
console.log(
|
|
18840
|
-
" " + chalk17.dim("Type ") + chalk17.cyan("yes") + chalk17.dim(" to make the plan. Type ") + chalk17.cyan("adjust") + chalk17.dim(" to change the objective. Type ") + chalk17.cyan("cancel") + chalk17.dim(" to answer questions first.")
|
|
18852
|
+
" " + chalk17.dim("Type ") + chalk17.cyan("yes") + chalk17.dim(" to make the plan. Type ") + chalk17.cyan("b") + chalk17.dim(" / ") + chalk17.cyan("adjust") + chalk17.dim(" to change the objective. Type ") + chalk17.cyan("cancel") + chalk17.dim(" to answer questions first.")
|
|
18841
18853
|
);
|
|
18842
18854
|
console.log();
|
|
18843
18855
|
return "Awaiting confirm";
|
|
@@ -18850,7 +18862,7 @@ async function handleStrategizeFlow(input, ctx) {
|
|
|
18850
18862
|
}
|
|
18851
18863
|
console.log();
|
|
18852
18864
|
console.log(
|
|
18853
|
-
" " + chalk17.dim("Type ") + chalk17.cyan("yes") + chalk17.dim(" to make the plan. Type ") + chalk17.cyan("adjust") + chalk17.dim(" to change the objective. Type ") + chalk17.cyan("cancel") + chalk17.dim(" to stop.")
|
|
18865
|
+
" " + chalk17.dim("Type ") + chalk17.cyan("yes") + chalk17.dim(" to make the plan. Type ") + chalk17.cyan("b") + chalk17.dim(" / ") + chalk17.cyan("adjust") + chalk17.dim(" to change the objective. Type ") + chalk17.cyan("cancel") + chalk17.dim(" to stop.")
|
|
18854
18866
|
);
|
|
18855
18867
|
console.log();
|
|
18856
18868
|
return "Awaiting confirm";
|
|
@@ -19027,7 +19039,7 @@ function printObjectiveCard(ctx, objective, proposed) {
|
|
|
19027
19039
|
);
|
|
19028
19040
|
console.log();
|
|
19029
19041
|
console.log(
|
|
19030
|
-
" " + chalk17.dim("Confirm? ") + chalk17.cyan("\u23CE yes") + chalk17.dim(" \xB7 ") + chalk17.cyan("adjust") + chalk17.dim(" \xB7 ") + chalk17.cyan("cancel")
|
|
19042
|
+
" " + chalk17.dim("Confirm? ") + chalk17.cyan("\u23CE yes") + chalk17.dim(" \xB7 ") + chalk17.cyan("b back") + chalk17.dim(" \xB7 ") + chalk17.cyan("adjust") + chalk17.dim(" \xB7 ") + chalk17.cyan("cancel")
|
|
19031
19043
|
);
|
|
19032
19044
|
console.log();
|
|
19033
19045
|
}
|
|
@@ -19170,7 +19182,7 @@ function buildSituationalAwarenessBlock(ctx, opts = {}) {
|
|
|
19170
19182
|
`Phase: ${phase} (${formatPhaseLabel(phase)}) \u2014 ${PHASE_MEANING[phase]}`
|
|
19171
19183
|
];
|
|
19172
19184
|
if (channel === "think") {
|
|
19173
|
-
lines.push("Channel: think \u2014 socratic partner; type done/cancel returns to \u203A");
|
|
19185
|
+
lines.push("Channel: think \u2014 socratic partner; type done/cancel/b back returns to \u203A");
|
|
19174
19186
|
lines.push("Response mode: deep (tools on)");
|
|
19175
19187
|
} else if (channel === "strategist") {
|
|
19176
19188
|
lines.push("Channel: strategist \u2014 measurable plan engine owns sequencing");
|
|
@@ -19214,11 +19226,13 @@ function buildSituationalAwarenessBlock(ctx, opts = {}) {
|
|
|
19214
19226
|
} else if (phase === "awaiting_data") {
|
|
19215
19227
|
lines.push("Already done: scope confirmed; analysis not ready");
|
|
19216
19228
|
lines.push(
|
|
19217
|
-
'Available now: tell the user to paste a CSV path, type "use demo data",
|
|
19229
|
+
'Available now: tell the user to paste a CSV path, type "use demo data", \u23CE go ahead when can_compute, or b/back to rewind the focus card \u2014 you cannot open files'
|
|
19218
19230
|
);
|
|
19219
19231
|
} else if (phase === "scope") {
|
|
19220
19232
|
lines.push("Already done: intent proposed; waiting on confirm");
|
|
19221
|
-
lines.push(
|
|
19233
|
+
lines.push(
|
|
19234
|
+
"Available now: wait for CLI confirm (\u23CE yes) or b/back/adjust \u2014 do not invent a different question"
|
|
19235
|
+
);
|
|
19222
19236
|
} else if (phase === "orient") {
|
|
19223
19237
|
lines.push("Already done: nothing locked yet");
|
|
19224
19238
|
lines.push("Available now: help the user name a focus; CLI will propose scope from their words");
|
|
@@ -19291,13 +19305,13 @@ var init_situation = __esm({
|
|
|
19291
19305
|
FUNNEL_SPINE = "Funnel: orient \u2192 scope \u2192 data \u2192 compute \u2192 explore | side doors: think, strategy, ship";
|
|
19292
19306
|
PHASE_MEANING = {
|
|
19293
19307
|
orient: "setup \u2014 open chat; user has not locked a scope yet",
|
|
19294
|
-
scope: "scope confirm \u2014 CLI owns yes/adjust; do not re-propose unless asked",
|
|
19295
|
-
awaiting_data: "data gate \u2014 load CSV/demo or compute; CLI owns the gate",
|
|
19308
|
+
scope: "scope confirm \u2014 CLI owns yes / b back / adjust; do not re-propose unless asked",
|
|
19309
|
+
awaiting_data: "data gate \u2014 load CSV/demo or compute; b/back rewinds to scope confirm (does not unload data); CLI owns the gate",
|
|
19296
19310
|
compute: "compute in progress \u2014 wait",
|
|
19297
19311
|
explore: "analysis complete \u2014 free-form Q&A on this session's artifact",
|
|
19298
|
-
think: "socratic think channel \u2014 return to \u203A via done/cancel",
|
|
19299
|
-
strategize: "strategist flow \u2014 objective confirm or plan drafting",
|
|
19300
|
-
deliver: "ship/handoff wizard \u2014 CLI owns write confirms"
|
|
19312
|
+
think: "socratic think channel \u2014 return to \u203A via done/cancel/b back",
|
|
19313
|
+
strategize: "strategist flow \u2014 objective confirm (yes / b back / adjust) or plan drafting",
|
|
19314
|
+
deliver: "ship/handoff wizard \u2014 CLI owns write confirms; b/back or cancel leaves the draft"
|
|
19301
19315
|
};
|
|
19302
19316
|
}
|
|
19303
19317
|
});
|