@sonnechasser/ntrp 2.3.2 → 2.4.1
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 +208 -116
- package/dist/mcp/server.js +30 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1584,7 +1584,7 @@ function printGuideCatalogLine(slide) {
|
|
|
1584
1584
|
function printDeepdiveHint(metricId, label) {
|
|
1585
1585
|
const name = label ?? metricId;
|
|
1586
1586
|
console.log(
|
|
1587
|
-
" " + chalk3.dim(`Ask what ${name.toLowerCase()} means \u2014 or `) + paint("accent", `/tour ${metricId}`) + chalk3.dim("
|
|
1587
|
+
" " + chalk3.dim(`Ask what ${name.toLowerCase()} means \u2014 or `) + paint("accent", `/tour ${metricId}`) + chalk3.dim(" if you want the card.")
|
|
1588
1588
|
);
|
|
1589
1589
|
console.log();
|
|
1590
1590
|
}
|
|
@@ -18358,7 +18358,24 @@ function listMetricExplainers(kind) {
|
|
|
18358
18358
|
function getCoreDeckExplainers() {
|
|
18359
18359
|
return CORE_DECK_IDS.map((id) => BY_ID.get(id)).filter(Boolean);
|
|
18360
18360
|
}
|
|
18361
|
-
|
|
18361
|
+
function buildVitalSignsPromptBlock() {
|
|
18362
|
+
return VITAL_IDS.map((id) => {
|
|
18363
|
+
const m = getMetricExplainer(id);
|
|
18364
|
+
if (!m) {
|
|
18365
|
+
throw new Error(`buildVitalSignsPromptBlock: missing explainer for ${id}`);
|
|
18366
|
+
}
|
|
18367
|
+
if (!m.dollar_label) {
|
|
18368
|
+
throw new Error(`buildVitalSignsPromptBlock: missing dollar_label for ${id}`);
|
|
18369
|
+
}
|
|
18370
|
+
return [
|
|
18371
|
+
`- ${m.id}: ${m.tagline}`,
|
|
18372
|
+
` Teach: ${m.meaning}`,
|
|
18373
|
+
` Expert read: ${m.expert_read}`,
|
|
18374
|
+
` Dollar label: ${m.dollar_label}`
|
|
18375
|
+
].join("\n");
|
|
18376
|
+
}).join("\n");
|
|
18377
|
+
}
|
|
18378
|
+
var VITALS, SAAS, METRIC_DEFINITIONS, CORE_DECK_IDS, BY_ID, ALIAS_INDEX, VITAL_IDS, SAAS_METRIC_IDS, GATING_LAYER_VISUAL;
|
|
18362
18379
|
var init_metric_definitions = __esm({
|
|
18363
18380
|
"src/data/metric-definitions.ts"() {
|
|
18364
18381
|
"use strict";
|
|
@@ -19165,6 +19182,13 @@ var init_metric_definitions = __esm({
|
|
|
19165
19182
|
idx.set("thread-depth", "thread_depth");
|
|
19166
19183
|
return idx;
|
|
19167
19184
|
})();
|
|
19185
|
+
VITAL_IDS = [
|
|
19186
|
+
"freshness",
|
|
19187
|
+
"flow_rate",
|
|
19188
|
+
"drop_rate",
|
|
19189
|
+
"signal_to_noise",
|
|
19190
|
+
"thread_depth"
|
|
19191
|
+
];
|
|
19168
19192
|
SAAS_METRIC_IDS = SAAS.map((m) => m.id);
|
|
19169
19193
|
GATING_LAYER_VISUAL = {
|
|
19170
19194
|
kind: "layer_stack",
|
|
@@ -25926,12 +25950,9 @@ var init_ghost_hints = __esm({
|
|
|
25926
25950
|
init_suggested_asks();
|
|
25927
25951
|
PHASE_GHOST_HINTS = {
|
|
25928
25952
|
orient: [
|
|
25929
|
-
'try "pipeline health"',
|
|
25930
25953
|
'try "how healthy is the pipeline?"',
|
|
25931
|
-
'try "what
|
|
25932
|
-
'try "
|
|
25933
|
-
'try "what is the most expensive problem to solve?"',
|
|
25934
|
-
'try "board deck on Q3"'
|
|
25954
|
+
'try "what does freshness mean?"',
|
|
25955
|
+
'try "what should I do next?"'
|
|
25935
25956
|
],
|
|
25936
25957
|
awaiting_data: [
|
|
25937
25958
|
'try "use demo data"',
|
|
@@ -36740,7 +36761,7 @@ async function handler19(args, ctx) {
|
|
|
36740
36761
|
console.log(chalk51.dim(` Trigger: ${triggerLabel} \u2014 ${play.trigger_condition}`));
|
|
36741
36762
|
if (play.trigger_vital_sign) {
|
|
36742
36763
|
console.log(
|
|
36743
|
-
chalk51.dim(" Ask what ") + chalk51.dim(play.trigger_vital_sign.replace(/_/g, " ")) + chalk51.dim(" means \u2014 or ") + paint("accent", `/tour ${play.trigger_vital_sign}`) + chalk51.dim("
|
|
36764
|
+
chalk51.dim(" Ask what ") + chalk51.dim(play.trigger_vital_sign.replace(/_/g, " ")) + chalk51.dim(" means \u2014 or ") + paint("accent", `/tour ${play.trigger_vital_sign}`) + chalk51.dim(" if you want the card.")
|
|
36744
36765
|
);
|
|
36745
36766
|
}
|
|
36746
36767
|
console.log();
|
|
@@ -40471,7 +40492,7 @@ function getDeepdiveNudge(ctx) {
|
|
|
40471
40492
|
if (!hasAnalysisForDeepdiveNudge(ctx)) return null;
|
|
40472
40493
|
return {
|
|
40473
40494
|
text: "Ask how healthy the pipeline looks",
|
|
40474
|
-
tip: "Or /tour
|
|
40495
|
+
tip: "We check if the number is real \u2014 then where deals stick, leak, or go thin. Two checks use our names. Or /tour if you want the deck.",
|
|
40475
40496
|
command: "/tour"
|
|
40476
40497
|
};
|
|
40477
40498
|
}
|
|
@@ -40807,16 +40828,12 @@ var init_metric_tour = __esm({
|
|
|
40807
40828
|
TOUR_SKIPPED_KEY = "metrics-tour-skipped";
|
|
40808
40829
|
HOME_NUDGE_SEEN_KEY = "metrics-tour-home-nudge-seen";
|
|
40809
40830
|
METRICS_TOUR_MILESTONE_ID = "metrics_tour";
|
|
40810
|
-
TOUR_INTRO_TITLE = "
|
|
40831
|
+
TOUR_INTRO_TITLE = "Are these pipeline numbers trustworthy \u2014 and where money leaks?";
|
|
40811
40832
|
TOUR_CLOSE_TITLE = "Curious? Start listening";
|
|
40812
40833
|
TOUR_INTRO_LINES = [
|
|
40813
|
-
"
|
|
40814
|
-
"",
|
|
40815
|
-
"
|
|
40816
|
-
"",
|
|
40817
|
-
"Vital signs (after) \u2014 Freshness, Flow Rate, Drop Rate, Signal:Noise, Thread Depth. These are our stethoscope: each score has a dollar translation, and we read them in layer order so an upstream red doesn't get papered over by a prettier downstream number.",
|
|
40818
|
-
"",
|
|
40819
|
-
"How to use NTRP (after vitals) \u2014 ask in English, peek at the glossary without a key, teach your desktop AI an inbox once, then stay in diagnose \u2192 plan \u2192 review."
|
|
40834
|
+
"Read in order: Freshness (is the number true?) \u2192 Flow + Drop (stuck / handoff) \u2192 Signal + Thread (busywork / thin deals).",
|
|
40835
|
+
"Freshness, Flow, and Drop feel familiar. Signal:Noise and Thread Depth are NTRP names.",
|
|
40836
|
+
"Then ask: what should I do next?"
|
|
40820
40837
|
];
|
|
40821
40838
|
TOUR_CLOSE_LINES = [
|
|
40822
40839
|
"A good first loop: ask something you actually care about \u2192 confirm the scope \u2192 load data (demo is fine) \u2192 let the formulas run. Then poke around:",
|
|
@@ -43059,6 +43076,7 @@ var init_prompt_parts = __esm({
|
|
|
43059
43076
|
init_profile();
|
|
43060
43077
|
init_store();
|
|
43061
43078
|
init_gtm_counsel();
|
|
43079
|
+
init_metric_definitions();
|
|
43062
43080
|
init_playbook();
|
|
43063
43081
|
init_play_outcomes();
|
|
43064
43082
|
init_registry2();
|
|
@@ -43095,16 +43113,7 @@ Restraint matters: NTRP is a stethoscope, not a surgeon. Observe, connect, and r
|
|
|
43095
43113
|
- Observe, connect, recommend \u2014 never execute CRM changes, send email, or claim an action was taken unless a tool result in this conversation confirms it.
|
|
43096
43114
|
- Weak or empty tool result: vary the arguments or approach once before concluding; if it's still empty, say what you'd need rather than filling the gap with plausible-sounding numbers.
|
|
43097
43115
|
- Never fabricate CRM records, people, companies, or dollar amounts.`;
|
|
43098
|
-
VITAL_SIGNS_BLOCK =
|
|
43099
|
-
Expert read: cut by owner and by stage first \u2014 freshness reds concentrate on people or process, rarely evenly. In a long-cycle enterprise motion 30 quiet days can be normal cadence; in a velocity motion it's a dead deal. A sudden cliff usually means a broken integration or a departed rep, not gradual decay. False positive to check: bulk-imported records nobody has touched yet.
|
|
43100
|
-
- flow_rate: Deal velocity. Low = stuck pipeline, slow progression. Dollar value = amount stuck in pipeline.
|
|
43101
|
-
Expert read: cut by stage-age, not just deal-age \u2014 find the stage where deals go to die (usually one). Compare stuck-deal age to this company's own median cycle, not a generic norm. Stuck + past-due close dates together signal happy-ears forecasting, a credibility problem before it's a revenue problem.
|
|
43102
|
-
- drop_rate: Handoff retention. Low = leads vanishing between marketing and sales. Dollar value = estimated lost revenue at handoff.
|
|
43103
|
-
Expert read: this is almost always a systems failure \u2014 routing rules, unassigned territories, dead rep queues, or a sync gap between marketing and CRM \u2014 not lazy reps. First cut by lead source; the leak usually concentrates in one or two sources. The cheapest pipeline this business can buy is the leads it already paid for.
|
|
43104
|
-
- signal_to_noise: Activity efficiency. Low = effort aimed at dead ends. Dollar value = cost of misdirected effort.
|
|
43105
|
-
Expert read: cut by rep and by account status \u2014 noise usually means reps fishing in the pond they can see (dead accounts they know) because targeting and account lists are stale. Persistent noise is a coverage-model problem, not a coaching problem. Check whether activity is logged against closed or unlinked records \u2014 often a hygiene artifact.
|
|
43106
|
-
- thread_depth: Deal resilience. Low = single-threaded deals, fragile pipeline. Dollar value = amount in single-threaded deals.
|
|
43107
|
-
Expert read: weight by deal size \u2014 one single-threaded mega-deal outweighs ten small ones. Single-threading late in the cycle is far more dangerous than early. In enterprise motions, thread depth is a leading indicator of slipped quarters: champions change jobs, and there's no second door in.`;
|
|
43116
|
+
VITAL_SIGNS_BLOCK = buildVitalSignsPromptBlock();
|
|
43108
43117
|
PLAYBOOK_BLOCK = `- "Multi-Thread Your Deals" (id: multi-thread-deals) \u2014 when thread_depth is low
|
|
43109
43118
|
- "Clean Dead Pipeline" (id: clean-dead-pipeline) \u2014 when freshness is low
|
|
43110
43119
|
- "Fix the Handoff Gap" (id: fix-handoff-gap) \u2014 when drop_rate is high and the source\u2192owner path is unknown
|
|
@@ -45759,12 +45768,89 @@ var init_health_chat = __esm({
|
|
|
45759
45768
|
}
|
|
45760
45769
|
});
|
|
45761
45770
|
|
|
45771
|
+
// src/conversation/next-move-chat.ts
|
|
45772
|
+
var next_move_chat_exports = {};
|
|
45773
|
+
__export(next_move_chat_exports, {
|
|
45774
|
+
NEXT_MOVE_EMPTY_LINE: () => NEXT_MOVE_EMPTY_LINE,
|
|
45775
|
+
everydayPlayReason: () => everydayPlayReason,
|
|
45776
|
+
isNextMoveChatPhase: () => isNextMoveChatPhase,
|
|
45777
|
+
isNextMoveIntent: () => isNextMoveIntent,
|
|
45778
|
+
resolveNextMove: () => resolveNextMove,
|
|
45779
|
+
tryNextMoveChat: () => tryNextMoveChat
|
|
45780
|
+
});
|
|
45781
|
+
import chalk95 from "chalk";
|
|
45782
|
+
function isNextMoveIntent(line) {
|
|
45783
|
+
const text = line.trim();
|
|
45784
|
+
if (!text) return false;
|
|
45785
|
+
if (/^(\/strategy|strategy)\b/i.test(text)) return false;
|
|
45786
|
+
return NEXT_MOVE_INTENT_RE.test(text);
|
|
45787
|
+
}
|
|
45788
|
+
function isNextMoveChatPhase(ctx) {
|
|
45789
|
+
const phase = resolveConversationPhase(ctx);
|
|
45790
|
+
return phase === "explore" || phase === "orient" && isAnalysisReady(ctx);
|
|
45791
|
+
}
|
|
45792
|
+
function everydayPlayReason(why) {
|
|
45793
|
+
const plain = why.replace(/\s+/g, " ").trim();
|
|
45794
|
+
if (!plain) return "";
|
|
45795
|
+
const match = plain.match(/^(.+?[.!?])(\s|$)/);
|
|
45796
|
+
const sentence = (match ? match[1] : plain).trim();
|
|
45797
|
+
return sentence.endsWith(".") || sentence.endsWith("!") || sentence.endsWith("?") ? sentence : `${sentence}.`;
|
|
45798
|
+
}
|
|
45799
|
+
function resolveNextMove(ctx) {
|
|
45800
|
+
const aggregate = ctx.snapshot.computeResult?.aggregate;
|
|
45801
|
+
if (!aggregate?.gating_vital_sign) return null;
|
|
45802
|
+
const gating = aggregate.gating_vital_sign;
|
|
45803
|
+
const play = getPlaysForVitalSign(gating)[0];
|
|
45804
|
+
if (!play) return null;
|
|
45805
|
+
const reason = everydayPlayReason(play.why);
|
|
45806
|
+
if (!reason) return null;
|
|
45807
|
+
return {
|
|
45808
|
+
playId: play.id,
|
|
45809
|
+
playName: play.name,
|
|
45810
|
+
reason,
|
|
45811
|
+
gatingVital: VITAL_SIGN_LABELS[gating] ?? gating
|
|
45812
|
+
};
|
|
45813
|
+
}
|
|
45814
|
+
function tryNextMoveChat(ctx, line) {
|
|
45815
|
+
if (!isNextMoveIntent(line)) return false;
|
|
45816
|
+
if (!isNextMoveChatPhase(ctx)) return false;
|
|
45817
|
+
const move = resolveNextMove(ctx);
|
|
45818
|
+
console.log();
|
|
45819
|
+
if (!move) {
|
|
45820
|
+
console.log(" " + NEXT_MOVE_EMPTY_LINE);
|
|
45821
|
+
console.log();
|
|
45822
|
+
recordMessage(ctx, "user", line);
|
|
45823
|
+
recordMessage(ctx, "agent", NEXT_MOVE_EMPTY_LINE);
|
|
45824
|
+
saveSessionState(ctx);
|
|
45825
|
+
return true;
|
|
45826
|
+
}
|
|
45827
|
+
console.log(" " + chalk95.bold(move.playName));
|
|
45828
|
+
console.log(" " + move.reason);
|
|
45829
|
+
console.log();
|
|
45830
|
+
recordMessage(ctx, "user", line);
|
|
45831
|
+
recordMessage(ctx, "agent", `${move.playName} \u2014 ${move.reason}`);
|
|
45832
|
+
saveSessionState(ctx);
|
|
45833
|
+
return true;
|
|
45834
|
+
}
|
|
45835
|
+
var NEXT_MOVE_EMPTY_LINE, NEXT_MOVE_INTENT_RE;
|
|
45836
|
+
var init_next_move_chat = __esm({
|
|
45837
|
+
"src/conversation/next-move-chat.ts"() {
|
|
45838
|
+
"use strict";
|
|
45839
|
+
init_context2();
|
|
45840
|
+
init_playbook();
|
|
45841
|
+
init_formatters();
|
|
45842
|
+
init_phase();
|
|
45843
|
+
NEXT_MOVE_EMPTY_LINE = "Nothing clear to recommend yet. Ask how healthy the pipeline looks.";
|
|
45844
|
+
NEXT_MOVE_INTENT_RE = /\b((what\s+should\s+i\s+do\s+next)|((what'?s|whats|what\s+is)\s+(the\s+)?next\s+move)|((what'?s|whats|what\s+is)\s+my\s+next\s+move))\b/i;
|
|
45845
|
+
}
|
|
45846
|
+
});
|
|
45847
|
+
|
|
45762
45848
|
// src/conversation/router.ts
|
|
45763
45849
|
var router_exports = {};
|
|
45764
45850
|
__export(router_exports, {
|
|
45765
45851
|
conversationRouter: () => conversationRouter
|
|
45766
45852
|
});
|
|
45767
|
-
import
|
|
45853
|
+
import chalk96 from "chalk";
|
|
45768
45854
|
function popModalState(ctx) {
|
|
45769
45855
|
const popped = [];
|
|
45770
45856
|
if (ctx.strategistState) {
|
|
@@ -45797,7 +45883,7 @@ function handleBackNavigation(ctx, line) {
|
|
|
45797
45883
|
}
|
|
45798
45884
|
if (phase === "scope") {
|
|
45799
45885
|
console.log();
|
|
45800
|
-
console.log(" " +
|
|
45886
|
+
console.log(" " + chalk96.dim("What should we focus on instead?"));
|
|
45801
45887
|
ctx.scope = void 0;
|
|
45802
45888
|
clearPendingAsk(ctx);
|
|
45803
45889
|
saveSessionState(ctx);
|
|
@@ -45817,7 +45903,7 @@ function handleBackNavigation(ctx, line) {
|
|
|
45817
45903
|
printScopeProposal(ctx);
|
|
45818
45904
|
if (hadData || hadAnalysis) {
|
|
45819
45905
|
console.log(
|
|
45820
|
-
" " +
|
|
45906
|
+
" " + chalk96.dim(
|
|
45821
45907
|
"Focus gate rewound \u2014 loaded data and any analysis stay. `b` does not unload demo data or undo compute."
|
|
45822
45908
|
)
|
|
45823
45909
|
);
|
|
@@ -45833,7 +45919,7 @@ function handleBackNavigation(ctx, line) {
|
|
|
45833
45919
|
recordMessage(ctx, "user", line);
|
|
45834
45920
|
recordMessage(ctx, "agent", "Strategy objective adjust (back)");
|
|
45835
45921
|
console.log();
|
|
45836
|
-
console.log(" " +
|
|
45922
|
+
console.log(" " + chalk96.dim("What is the objective? State a finish line."));
|
|
45837
45923
|
console.log();
|
|
45838
45924
|
return { handled: true, summary: "Awaiting objective" };
|
|
45839
45925
|
}
|
|
@@ -45845,7 +45931,7 @@ function handleBackNavigation(ctx, line) {
|
|
|
45845
45931
|
const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
|
|
45846
45932
|
console.log();
|
|
45847
45933
|
console.log(
|
|
45848
|
-
" " +
|
|
45934
|
+
" " + chalk96.dim(`Back \u2014 dropped ${popped.join(" and ")}. At `) + chalk96.cyan(backTo) + chalk96.dim(".")
|
|
45849
45935
|
);
|
|
45850
45936
|
console.log();
|
|
45851
45937
|
return { handled: true, summary: "Back" };
|
|
@@ -45859,7 +45945,7 @@ function handleBackNavigation(ctx, line) {
|
|
|
45859
45945
|
const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
|
|
45860
45946
|
console.log();
|
|
45861
45947
|
console.log(
|
|
45862
|
-
" " +
|
|
45948
|
+
" " + chalk96.dim(`Back \u2014 dropped ${popped.join(" and ")}. At `) + chalk96.cyan(backTo) + chalk96.dim(".")
|
|
45863
45949
|
);
|
|
45864
45950
|
console.log();
|
|
45865
45951
|
return { handled: true, summary: "Back" };
|
|
@@ -45903,7 +45989,7 @@ async function conversationRouter(input, ctx) {
|
|
|
45903
45989
|
if (!ok) {
|
|
45904
45990
|
console.log();
|
|
45905
45991
|
console.log(
|
|
45906
|
-
" " +
|
|
45992
|
+
" " + chalk96.dim("Staying on this session. Type ") + chalk96.cyan("/home") + chalk96.dim(" for the dashboard.")
|
|
45907
45993
|
);
|
|
45908
45994
|
console.log();
|
|
45909
45995
|
return { handled: true };
|
|
@@ -45918,7 +46004,7 @@ async function conversationRouter(input, ctx) {
|
|
|
45918
46004
|
}
|
|
45919
46005
|
console.log();
|
|
45920
46006
|
console.log(
|
|
45921
|
-
" " +
|
|
46007
|
+
" " + chalk96.dim("Start a fresh analysis with ") + chalk96.cyan("/new") + chalk96.dim(" \u2014 or ") + chalk96.cyan("/home") + chalk96.dim(" for the dashboard.")
|
|
45922
46008
|
);
|
|
45923
46009
|
console.log();
|
|
45924
46010
|
return { handled: true };
|
|
@@ -45932,7 +46018,7 @@ async function conversationRouter(input, ctx) {
|
|
|
45932
46018
|
const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
|
|
45933
46019
|
console.log();
|
|
45934
46020
|
console.log(
|
|
45935
|
-
" " +
|
|
46021
|
+
" " + chalk96.dim(`Cancelled \u2014 dropped ${popped.join(" and ")}. Back to `) + chalk96.cyan(backTo) + chalk96.dim(".")
|
|
45936
46022
|
);
|
|
45937
46023
|
console.log();
|
|
45938
46024
|
return { handled: true, summary: "Cancelled" };
|
|
@@ -45982,6 +46068,12 @@ async function conversationRouter(input, ctx) {
|
|
|
45982
46068
|
return { handled: true, summary: "Pipeline health" };
|
|
45983
46069
|
}
|
|
45984
46070
|
}
|
|
46071
|
+
if (phase === "explore" || phase === "orient" && isAnalysisReady(ctx)) {
|
|
46072
|
+
const { tryNextMoveChat: tryNextMoveChat2 } = await Promise.resolve().then(() => (init_next_move_chat(), next_move_chat_exports));
|
|
46073
|
+
if (tryNextMoveChat2(ctx, line)) {
|
|
46074
|
+
return { handled: true, summary: "Next move" };
|
|
46075
|
+
}
|
|
46076
|
+
}
|
|
45985
46077
|
if (phase === "think") {
|
|
45986
46078
|
const summary = await handleThinkFlow(line, ctx) ?? void 0;
|
|
45987
46079
|
return { handled: true, summary };
|
|
@@ -46020,7 +46112,7 @@ async function conversationRouter(input, ctx) {
|
|
|
46020
46112
|
}
|
|
46021
46113
|
if (phase === "compute") {
|
|
46022
46114
|
console.log();
|
|
46023
|
-
console.log(" " +
|
|
46115
|
+
console.log(" " + chalk96.dim("Analysis running \u2014 wait for it to finish before typing another question."));
|
|
46024
46116
|
console.log();
|
|
46025
46117
|
return { handled: true };
|
|
46026
46118
|
}
|
|
@@ -46076,7 +46168,7 @@ __export(dispatch_exports, {
|
|
|
46076
46168
|
dispatch: () => dispatch,
|
|
46077
46169
|
replayPendingBlockedLine: () => replayPendingBlockedLine
|
|
46078
46170
|
});
|
|
46079
|
-
import
|
|
46171
|
+
import chalk97 from "chalk";
|
|
46080
46172
|
function printLicenseRequired(command) {
|
|
46081
46173
|
printLicenseBlocked(command);
|
|
46082
46174
|
}
|
|
@@ -46094,7 +46186,7 @@ async function replayPendingBlockedLine(ctx) {
|
|
|
46094
46186
|
if (!hasValidLicense()) return false;
|
|
46095
46187
|
ctx.pendingBlockedLine = void 0;
|
|
46096
46188
|
console.log();
|
|
46097
|
-
console.log(" " +
|
|
46189
|
+
console.log(" " + chalk97.dim("Picking up where you left off\u2026"));
|
|
46098
46190
|
console.log();
|
|
46099
46191
|
await dispatch(line, ctx);
|
|
46100
46192
|
return true;
|
|
@@ -46164,7 +46256,7 @@ async function dispatch(input, ctx) {
|
|
|
46164
46256
|
if (tokens.length === 1) {
|
|
46165
46257
|
if (/^\d$/.test(first)) {
|
|
46166
46258
|
console.log(
|
|
46167
|
-
" " +
|
|
46259
|
+
" " + chalk97.dim("Looks like a menu pick \u2014 run ") + paint("accent", "/new") + chalk97.dim(" to start (pick Demo, then choose your analysis type).")
|
|
46168
46260
|
);
|
|
46169
46261
|
return { kind: "handled" };
|
|
46170
46262
|
}
|
|
@@ -46187,19 +46279,19 @@ async function dispatch(input, ctx) {
|
|
|
46187
46279
|
return { kind: "handled", summary };
|
|
46188
46280
|
}
|
|
46189
46281
|
console.log(
|
|
46190
|
-
" " +
|
|
46282
|
+
" " + chalk97.dim("Not in Q&A yet. Confirm the scope, load data, and run analysis first. Type ") + paint("accent", "/home") + chalk97.dim(" for status.")
|
|
46191
46283
|
);
|
|
46192
46284
|
return { kind: "handled" };
|
|
46193
46285
|
}
|
|
46194
46286
|
console.log(
|
|
46195
|
-
" " +
|
|
46287
|
+
" " + chalk97.dim("Natural-language questions run inside ntrp. Start with ") + paint("accent", "ntrp") + chalk97.dim(" and type a question after analysis.")
|
|
46196
46288
|
);
|
|
46197
46289
|
return { kind: "handled" };
|
|
46198
46290
|
}
|
|
46199
46291
|
async function runSlashCommand(name, args, ctx) {
|
|
46200
46292
|
const handler54 = await resolveHandler(name);
|
|
46201
46293
|
if (!handler54) {
|
|
46202
|
-
console.error(
|
|
46294
|
+
console.error(chalk97.red(` Unknown command: /${name}`));
|
|
46203
46295
|
return void 0;
|
|
46204
46296
|
}
|
|
46205
46297
|
const result = await handler54(args, ctx);
|
|
@@ -46236,7 +46328,7 @@ var init_inline_suggestion = __esm({
|
|
|
46236
46328
|
});
|
|
46237
46329
|
|
|
46238
46330
|
// src/conversation/loop-guard.ts
|
|
46239
|
-
import
|
|
46331
|
+
import chalk98 from "chalk";
|
|
46240
46332
|
function createLoopGuardState() {
|
|
46241
46333
|
return { phase: null, stuckTurns: 0 };
|
|
46242
46334
|
}
|
|
@@ -46268,10 +46360,10 @@ function printLoopEscalation(phase) {
|
|
|
46268
46360
|
if (!guide) return;
|
|
46269
46361
|
console.log();
|
|
46270
46362
|
console.log(
|
|
46271
|
-
" " +
|
|
46363
|
+
" " + chalk98.yellow("We seem to be going in circles \u2014 you're in ") + paint("accent", guide.mode) + chalk98.yellow(" mode.")
|
|
46272
46364
|
);
|
|
46273
|
-
console.log(" " +
|
|
46274
|
-
console.log(" " +
|
|
46365
|
+
console.log(" " + chalk98.dim("Right now I can only accept: ") + guide.accepts);
|
|
46366
|
+
console.log(" " + chalk98.dim("To leave: ") + guide.leave);
|
|
46275
46367
|
console.log();
|
|
46276
46368
|
}
|
|
46277
46369
|
var LOOP_GUARD_THRESHOLD, MODAL_PHASES, PHASE_GUIDES;
|
|
@@ -46315,7 +46407,7 @@ __export(welcome_exports, {
|
|
|
46315
46407
|
resolveWelcomeNextAction: () => resolveWelcomeNextAction,
|
|
46316
46408
|
staleProcessHomeNotice: () => staleProcessHomeNotice
|
|
46317
46409
|
});
|
|
46318
|
-
import
|
|
46410
|
+
import chalk99 from "chalk";
|
|
46319
46411
|
function formatHomeEntityCounts(counts) {
|
|
46320
46412
|
const parts = [];
|
|
46321
46413
|
const people = counts.people ?? 0;
|
|
@@ -46329,11 +46421,11 @@ function formatHomeEntityCounts(counts) {
|
|
|
46329
46421
|
return parts.join(" \xB7 ");
|
|
46330
46422
|
}
|
|
46331
46423
|
function formatEmptyDataHomeHint(savedSessionCount, opts = {}) {
|
|
46332
|
-
const onboard = opts.includeOnboard === true ?
|
|
46424
|
+
const onboard = opts.includeOnboard === true ? chalk99.dim(", or ") + paint("accent", "/onboard") + chalk99.dim(" to calibrate") : "";
|
|
46333
46425
|
if (savedSessionCount > 0) {
|
|
46334
|
-
return
|
|
46426
|
+
return chalk99.dim("Drop a CSV or type ") + paint("accent", "use demo data") + chalk99.dim(" to load a sample") + onboard + chalk99.dim(". Type ") + paint("accent", "/session") + chalk99.dim(" to open a saved session");
|
|
46335
46427
|
}
|
|
46336
|
-
return
|
|
46428
|
+
return chalk99.dim("Drop a CSV or type ") + paint("accent", "use demo data") + chalk99.dim(" to load a sample pipeline") + onboard;
|
|
46337
46429
|
}
|
|
46338
46430
|
function staleProcessHomeNotice() {
|
|
46339
46431
|
const running = getInstalledVersion();
|
|
@@ -46375,19 +46467,19 @@ function sessionSummaryText(s) {
|
|
|
46375
46467
|
summary: s.summary,
|
|
46376
46468
|
dataset: s.dataset
|
|
46377
46469
|
});
|
|
46378
|
-
return summary === NO_SUMMARY ?
|
|
46470
|
+
return summary === NO_SUMMARY ? chalk99.dim(summary) : summary;
|
|
46379
46471
|
}
|
|
46380
46472
|
function formatLastSessionLine(s, colW, ctx, opts) {
|
|
46381
46473
|
const phase = sessionPhaseLabel(s, ctx);
|
|
46382
|
-
const current = opts?.markCurrent && s.id === ctx?.sessionId ?
|
|
46383
|
-
const meta = `${formatSessionId(s.id, s.name)} ${
|
|
46474
|
+
const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk99.dim(" \xB7 current") : "";
|
|
46475
|
+
const meta = `${formatSessionId(s.id, s.name)} ${chalk99.dim("\xB7")} ${chalk99.dim(lensBadgeLabel(s.analysis))} ${chalk99.dim("\xB7")} ${paint("accent", phase)} ${chalk99.dim("\xB7")} ${sessionSummaryText(s)}${current}`;
|
|
46384
46476
|
return truncateVisible(` ${meta}`, colW);
|
|
46385
46477
|
}
|
|
46386
46478
|
function formatActiveSessionLine(s, colW, ctx, opts) {
|
|
46387
46479
|
const indent = " ";
|
|
46388
46480
|
const idPart = formatSessionId(s.id, s.name);
|
|
46389
|
-
const status =
|
|
46390
|
-
const current = opts?.markCurrent && s.id === ctx?.sessionId ?
|
|
46481
|
+
const status = chalk99.dim(` \xB7 ${sessionStatusSuffix(s)}`);
|
|
46482
|
+
const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk99.dim(" \xB7 current") : "";
|
|
46391
46483
|
const suffix = `${status}${current}`;
|
|
46392
46484
|
const summaryBudget = Math.max(8, colW - visibleWidth(indent) - visibleWidth(idPart) - visibleWidth(suffix) - 2);
|
|
46393
46485
|
const summaryPart = truncateVisible(sessionSummaryText(s), summaryBudget);
|
|
@@ -46428,13 +46520,13 @@ function buildSystemLines(colW, statusRows, recent) {
|
|
|
46428
46520
|
lines.push(sectionHeading("System"));
|
|
46429
46521
|
const labelW = Math.max(...statusRows.map((r) => r.label.length), "last used".length);
|
|
46430
46522
|
for (const item of statusRows) {
|
|
46431
|
-
const label =
|
|
46523
|
+
const label = chalk99.dim(padRight(item.label, labelW));
|
|
46432
46524
|
const state2 = padRight(item.state, 10);
|
|
46433
46525
|
const detailW = Math.max(1, colW - labelW - 13);
|
|
46434
|
-
lines.push(`${label} ${state2} ${
|
|
46526
|
+
lines.push(`${label} ${state2} ${chalk99.dim(truncateVisible(item.detail, detailW))}`);
|
|
46435
46527
|
}
|
|
46436
46528
|
if (recent) {
|
|
46437
|
-
lines.push(`${
|
|
46529
|
+
lines.push(`${chalk99.dim(padRight("last used", labelW))} ${chalk99.dim(recent)}`);
|
|
46438
46530
|
}
|
|
46439
46531
|
return lines;
|
|
46440
46532
|
}
|
|
@@ -46442,10 +46534,10 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
|
|
|
46442
46534
|
const lines = [""];
|
|
46443
46535
|
lines.push(sectionHeading("Last Session"));
|
|
46444
46536
|
if (!lastSession) {
|
|
46445
|
-
lines.push(` ${
|
|
46537
|
+
lines.push(` ${chalk99.dim("(none)")}`);
|
|
46446
46538
|
lines.push(
|
|
46447
46539
|
truncateVisible(
|
|
46448
|
-
` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${
|
|
46540
|
+
` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${chalk99.dim(nextAction.label)} ${chalk99.dim(nextAction.detail)}`}`,
|
|
46449
46541
|
colW
|
|
46450
46542
|
)
|
|
46451
46543
|
);
|
|
@@ -46459,7 +46551,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
|
|
|
46459
46551
|
if (!isCurrent) {
|
|
46460
46552
|
lines.push(
|
|
46461
46553
|
truncateVisible(
|
|
46462
|
-
` ${
|
|
46554
|
+
` ${chalk99.dim("Resume:")} ${paint("accent", `/session ${lastSession.id.slice(-4)}`)}`,
|
|
46463
46555
|
colW
|
|
46464
46556
|
)
|
|
46465
46557
|
);
|
|
@@ -46468,7 +46560,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
|
|
|
46468
46560
|
truncateVisible(` ${actionHint(nextAction.label, nextAction.command, nextAction.detail)}`, colW)
|
|
46469
46561
|
);
|
|
46470
46562
|
} else {
|
|
46471
|
-
lines.push(truncateVisible(` ${
|
|
46563
|
+
lines.push(truncateVisible(` ${chalk99.dim(nextAction.label)} ${chalk99.dim(nextAction.detail)}`, colW));
|
|
46472
46564
|
}
|
|
46473
46565
|
if (isCurrent && emptyDataHint) {
|
|
46474
46566
|
lines.push(truncateVisible(` ${emptyDataHint}`, colW));
|
|
@@ -46479,14 +46571,14 @@ function buildActiveSessionsLines(colW, ctx, activeSessions) {
|
|
|
46479
46571
|
const lines = [""];
|
|
46480
46572
|
lines.push(sectionHeading("Active Sessions"));
|
|
46481
46573
|
if (activeSessions.length === 0) {
|
|
46482
|
-
lines.push(` ${
|
|
46574
|
+
lines.push(` ${chalk99.dim("(none in progress)")}`);
|
|
46483
46575
|
return lines;
|
|
46484
46576
|
}
|
|
46485
46577
|
for (const s of activeSessions.slice(0, 5)) {
|
|
46486
46578
|
lines.push(formatActiveSessionLine(s, colW, ctx, { markCurrent: true }));
|
|
46487
46579
|
}
|
|
46488
46580
|
if (activeSessions.length > 5) {
|
|
46489
|
-
lines.push(` ${
|
|
46581
|
+
lines.push(` ${chalk99.dim(`+${activeSessions.length - 5} more \xB7 `)}${paint("accent", "/session")}`);
|
|
46490
46582
|
}
|
|
46491
46583
|
return lines;
|
|
46492
46584
|
}
|
|
@@ -46574,7 +46666,7 @@ async function printWelcome(ctx, version) {
|
|
|
46574
46666
|
const gap = Math.max(0, innerW - versionTag.length);
|
|
46575
46667
|
const gapL = Math.floor(gap / 2);
|
|
46576
46668
|
push(
|
|
46577
|
-
border(`\u256D${"\u2500".repeat(gapL)}`) +
|
|
46669
|
+
border(`\u256D${"\u2500".repeat(gapL)}`) + chalk99.dim(versionTag) + border(`${"\u2500".repeat(gap - gapL)}\u256E`)
|
|
46578
46670
|
);
|
|
46579
46671
|
if (useWideLayout) {
|
|
46580
46672
|
const leftLines = systemLines;
|
|
@@ -46601,7 +46693,7 @@ async function printWelcome(ctx, version) {
|
|
|
46601
46693
|
push(border(`\u2570${"\u2500".repeat(innerW)}\u256F`));
|
|
46602
46694
|
push(
|
|
46603
46695
|
truncateVisible(
|
|
46604
|
-
license.valid ? ` ${paint("accent", "/help")}${
|
|
46696
|
+
license.valid ? ` ${paint("accent", "/help")}${chalk99.dim(" commands \xB7 ")}${paint("accent", "/tour")}${chalk99.dim(" tour \xB7 ")}${paint("accent", "/progress")}${chalk99.dim(" hours \xB7 ")}${paint("accent", "/session")}${chalk99.dim(" resume")}` : ` ${paint("accent", "/help")}${chalk99.dim(" commands \xB7 ")}${paint("accent", "/activate")}${chalk99.dim(" paste a key \xB7 ")}${paint("accent", "/checkout")}${chalk99.dim(" signup \xB7 ")}${paint("accent", "/progress")}${chalk99.dim(" hours")}`,
|
|
46605
46697
|
cardW
|
|
46606
46698
|
)
|
|
46607
46699
|
);
|
|
@@ -46612,7 +46704,7 @@ async function printWelcome(ctx, version) {
|
|
|
46612
46704
|
if (strategyNudge) {
|
|
46613
46705
|
push(
|
|
46614
46706
|
truncateVisible(
|
|
46615
|
-
` ${paint("warning", "\u2691")} ${
|
|
46707
|
+
` ${paint("warning", "\u2691")} ${chalk99.dim(strategyNudge.text)} ${chalk99.dim("\xB7")} ${paint("accent", strategyNudge.command)}`,
|
|
46616
46708
|
cardW
|
|
46617
46709
|
)
|
|
46618
46710
|
);
|
|
@@ -46620,7 +46712,7 @@ async function printWelcome(ctx, version) {
|
|
|
46620
46712
|
const tip = deepdiveNudge.tip ?? deepdiveNudge.command;
|
|
46621
46713
|
push(
|
|
46622
46714
|
truncateVisible(
|
|
46623
|
-
tip ? ` ${paint("warning", "\u2691")} ${
|
|
46715
|
+
tip ? ` ${paint("warning", "\u2691")} ${chalk99.dim(deepdiveNudge.text)} ${chalk99.dim("\xB7")} ${chalk99.dim(tip)}` : ` ${paint("warning", "\u2691")} ${chalk99.dim(deepdiveNudge.text)}`,
|
|
46624
46716
|
cardW
|
|
46625
46717
|
)
|
|
46626
46718
|
);
|
|
@@ -46628,7 +46720,7 @@ async function printWelcome(ctx, version) {
|
|
|
46628
46720
|
} else if (voiceNudge) {
|
|
46629
46721
|
push(
|
|
46630
46722
|
truncateVisible(
|
|
46631
|
-
` ${paint("warning", "\u2691")} ${
|
|
46723
|
+
` ${paint("warning", "\u2691")} ${chalk99.dim(voiceNudge.text)} ${chalk99.dim("\xB7")} ${paint("accent", voiceNudge.command)}`,
|
|
46632
46724
|
cardW
|
|
46633
46725
|
)
|
|
46634
46726
|
);
|
|
@@ -46816,7 +46908,7 @@ __export(repl_exports, {
|
|
|
46816
46908
|
});
|
|
46817
46909
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
46818
46910
|
import { clearLine as clearLine2, cursorTo as cursorTo2 } from "readline";
|
|
46819
|
-
import
|
|
46911
|
+
import chalk100 from "chalk";
|
|
46820
46912
|
import { join as join42 } from "path";
|
|
46821
46913
|
function buildPrompt(ctx) {
|
|
46822
46914
|
return buildConversationPrompt(ctx);
|
|
@@ -46908,12 +47000,12 @@ function renderInlineSuggestion(rl, prompt, ctx) {
|
|
|
46908
47000
|
suggestionPainted = suffix !== null;
|
|
46909
47001
|
clearLine2(process.stdout, 0);
|
|
46910
47002
|
cursorTo2(process.stdout, 0);
|
|
46911
|
-
process.stdout.write(prompt + line + (suffix ?
|
|
47003
|
+
process.stdout.write(prompt + line + (suffix ? chalk100.dim(suffix) : ""));
|
|
46912
47004
|
cursorTo2(process.stdout, promptWidth + cursor);
|
|
46913
47005
|
}
|
|
46914
47006
|
function appendTurnLine(current, promptLabel, currentSummary) {
|
|
46915
|
-
const currentLine = currentSummary ? `${promptLabel} ${current} ${
|
|
46916
|
-
console.log(" " +
|
|
47007
|
+
const currentLine = currentSummary ? `${promptLabel} ${current} ${chalk100.white("\u2192")} ${currentSummary}` : `${promptLabel} ${current}`;
|
|
47008
|
+
console.log(" " + chalk100.dim(currentLine));
|
|
46917
47009
|
console.log();
|
|
46918
47010
|
}
|
|
46919
47011
|
async function goHome(ctx, version, history, opts) {
|
|
@@ -46923,7 +47015,7 @@ async function goHome(ctx, version, history, opts) {
|
|
|
46923
47015
|
clearTerminalHome();
|
|
46924
47016
|
if (opts?.banner) {
|
|
46925
47017
|
console.log();
|
|
46926
|
-
console.log(" " + paint("accent", "\u2713") + " " +
|
|
47018
|
+
console.log(" " + paint("accent", "\u2713") + " " + chalk100.dim(opts.banner));
|
|
46927
47019
|
}
|
|
46928
47020
|
await printWelcome(ctx, version);
|
|
46929
47021
|
}
|
|
@@ -46946,11 +47038,11 @@ async function handleDispatchResult(result, ctx, version, history) {
|
|
|
46946
47038
|
case "unknown":
|
|
46947
47039
|
if (result.suggestion) {
|
|
46948
47040
|
console.log(
|
|
46949
|
-
" " +
|
|
47041
|
+
" " + chalk100.red(`Unknown command: ${result.token}.`) + chalk100.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk100.dim("?")
|
|
46950
47042
|
);
|
|
46951
47043
|
} else {
|
|
46952
47044
|
console.log(
|
|
46953
|
-
" " +
|
|
47045
|
+
" " + chalk100.red(`Unknown command: ${result.token}`) + chalk100.dim(" Type ") + paint("accent", "/help") + chalk100.dim(" to see available commands.")
|
|
46954
47046
|
);
|
|
46955
47047
|
}
|
|
46956
47048
|
break;
|
|
@@ -46974,7 +47066,7 @@ async function runRepl(ctx, version) {
|
|
|
46974
47066
|
});
|
|
46975
47067
|
ctx.rl = rl;
|
|
46976
47068
|
console.log();
|
|
46977
|
-
console.log(" " +
|
|
47069
|
+
console.log(" " + chalk100.dim("What do you want to look at?"));
|
|
46978
47070
|
console.log();
|
|
46979
47071
|
if (ctx.pendingUpdateCheck) {
|
|
46980
47072
|
void ctx.pendingUpdateCheck.then((result) => {
|
|
@@ -47016,7 +47108,7 @@ async function runRepl(ctx, version) {
|
|
|
47016
47108
|
return;
|
|
47017
47109
|
}
|
|
47018
47110
|
sigintPrimed = true;
|
|
47019
|
-
console.log("\n " +
|
|
47111
|
+
console.log("\n " + chalk100.dim("Type /exit to quit, or press Ctrl+C again."));
|
|
47020
47112
|
};
|
|
47021
47113
|
rl.on("SIGINT", sigintHandler);
|
|
47022
47114
|
function shutdownRepl() {
|
|
@@ -47053,7 +47145,7 @@ async function runRepl(ctx, version) {
|
|
|
47053
47145
|
if (!typed && !enterAction) {
|
|
47054
47146
|
clearGhostRowAfterSubmit();
|
|
47055
47147
|
const coach = consumeOrientEmptyEnterCoach(ctx);
|
|
47056
|
-
if (coach) console.log(" " +
|
|
47148
|
+
if (coach) console.log(" " + chalk100.dim(coach));
|
|
47057
47149
|
continue;
|
|
47058
47150
|
}
|
|
47059
47151
|
const line = typed || enterAction.submit;
|
|
@@ -47104,11 +47196,11 @@ async function runRepl(ctx, version) {
|
|
|
47104
47196
|
ctx.wizardDepth = 0;
|
|
47105
47197
|
ctx.secretInputActive = false;
|
|
47106
47198
|
if (err instanceof Error && err.message === "Cancelled") {
|
|
47107
|
-
console.log(" " +
|
|
47199
|
+
console.log(" " + chalk100.dim("Cancelled."));
|
|
47108
47200
|
} else {
|
|
47109
47201
|
const { tryRecoverLlmAuthFailure: tryRecoverLlmAuthFailure2 } = await Promise.resolve().then(() => (init_auth_recovery(), auth_recovery_exports));
|
|
47110
47202
|
if (!await tryRecoverLlmAuthFailure2(ctx, err)) {
|
|
47111
|
-
console.error(" " +
|
|
47203
|
+
console.error(" " + chalk100.red("Error: " + String(err.message ?? err)));
|
|
47112
47204
|
}
|
|
47113
47205
|
}
|
|
47114
47206
|
}
|
|
@@ -47135,10 +47227,10 @@ async function runRepl(ctx, version) {
|
|
|
47135
47227
|
await closeSession(ctx);
|
|
47136
47228
|
}
|
|
47137
47229
|
if (isTranscriptActive(ctx.sessionId)) {
|
|
47138
|
-
console.log(" " +
|
|
47139
|
-
console.log(" " +
|
|
47230
|
+
console.log(" " + chalk100.dim("Transcript: ") + chalk100.dim(transcriptPathForSession(ctx.sessionId)));
|
|
47231
|
+
console.log(" " + chalk100.dim("Context brief: ") + chalk100.dim(contextDocPathForSession(ctx.sessionId)));
|
|
47140
47232
|
}
|
|
47141
|
-
console.log(" " +
|
|
47233
|
+
console.log(" " + chalk100.dim(randomGoodbye()));
|
|
47142
47234
|
}
|
|
47143
47235
|
function printHelpOneShot() {
|
|
47144
47236
|
printHelp();
|
|
@@ -47146,43 +47238,43 @@ function printHelpOneShot() {
|
|
|
47146
47238
|
function printHelp() {
|
|
47147
47239
|
console.log();
|
|
47148
47240
|
console.log(" " + sectionHeading("Conversation"));
|
|
47149
|
-
console.log(" " +
|
|
47150
|
-
console.log(" " +
|
|
47151
|
-
console.log(" " +
|
|
47152
|
-
console.log(" " +
|
|
47153
|
-
console.log(" " +
|
|
47154
|
-
console.log(" " +
|
|
47241
|
+
console.log(" " + chalk100.dim("Type the question. You do not need a slash command."));
|
|
47242
|
+
console.log(" " + chalk100.dim("Paste a CSV path or type ") + paint("accent", '"use demo data"') + chalk100.dim(" to load data."));
|
|
47243
|
+
console.log(" " + chalk100.dim("After analysis, type questions in English."));
|
|
47244
|
+
console.log(" " + chalk100.dim("Type ") + paint("accent", '"how should we fix this?"') + chalk100.dim(" to make a strategy. Type ") + paint("accent", "keep going") + chalk100.dim(" at confirm to keep working until the plan is ready."));
|
|
47245
|
+
console.log(" " + chalk100.dim("Type ") + paint("accent", '"ship a board deck"') + chalk100.dim(" to write a handoff."));
|
|
47246
|
+
console.log(" " + chalk100.dim("The ") + paint("accent", "\u203A") + chalk100.dim(" prompt shows brief or deep after analysis. Brief is the default."));
|
|
47155
47247
|
console.log();
|
|
47156
47248
|
console.log(" " + sectionHeading("Keys"));
|
|
47157
47249
|
console.log(
|
|
47158
|
-
" " + paint("accent", "\u23CE") +
|
|
47250
|
+
" " + paint("accent", "\u23CE") + chalk100.dim(
|
|
47159
47251
|
" Accepts the default. At the main prompt it runs the armed action (yes, use demo data, go ahead, /connect, /update, keep going)."
|
|
47160
47252
|
)
|
|
47161
47253
|
);
|
|
47162
47254
|
console.log(
|
|
47163
|
-
" " +
|
|
47255
|
+
" " + chalk100.dim(
|
|
47164
47256
|
" On yes/no questions and menus it accepts yes (or the recommended option). Type something else to decline or pick another path."
|
|
47165
47257
|
)
|
|
47166
47258
|
);
|
|
47167
47259
|
console.log(
|
|
47168
|
-
" " + paint("accent", "b") +
|
|
47260
|
+
" " + paint("accent", "b") + chalk100.dim(" / ") + paint("accent", "back") + chalk100.dim(" Steps back one confirm gate, or leaves a modal. Does not unload data or undo compute.")
|
|
47169
47261
|
);
|
|
47170
47262
|
console.log(
|
|
47171
|
-
" " +
|
|
47263
|
+
" " + chalk100.dim("On ") + paint("accent", "/settings") + chalk100.dim(" menus, ") + paint("accent", "b") + chalk100.dim(" leaves the hub (same as Done).")
|
|
47172
47264
|
);
|
|
47173
47265
|
console.log(
|
|
47174
|
-
" " + paint("accent", "more") +
|
|
47266
|
+
" " + paint("accent", "more") + chalk100.dim(" Shows the full strategy brief after the short summary.")
|
|
47175
47267
|
);
|
|
47176
47268
|
console.log(
|
|
47177
|
-
" " + paint("accent", "expand") +
|
|
47269
|
+
" " + paint("accent", "expand") + chalk100.dim(
|
|
47178
47270
|
" 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."
|
|
47179
47271
|
)
|
|
47180
47272
|
);
|
|
47181
47273
|
console.log(
|
|
47182
|
-
" " + paint("accent", "cancel") +
|
|
47274
|
+
" " + paint("accent", "cancel") + chalk100.dim(" Drops the current modal overlay (strategy, think, ship, unconfirmed scope).")
|
|
47183
47275
|
);
|
|
47184
47276
|
console.log(
|
|
47185
|
-
" " +
|
|
47277
|
+
" " + chalk100.dim("On ") + paint("accent", "/tour") + chalk100.dim(" slides, ") + paint("accent", "b") + chalk100.dim(" moves to the previous slide.")
|
|
47186
47278
|
);
|
|
47187
47279
|
console.log();
|
|
47188
47280
|
console.log(" " + sectionHeading("Shortcuts"));
|
|
@@ -47210,11 +47302,11 @@ function printHelp() {
|
|
|
47210
47302
|
];
|
|
47211
47303
|
const maxW = Math.max(...shortcuts.map(([c]) => c.length)) + 2;
|
|
47212
47304
|
for (const [cmd, desc] of shortcuts) {
|
|
47213
|
-
console.log(` ${paint("accent", padRight(cmd, maxW))} ${
|
|
47305
|
+
console.log(` ${paint("accent", padRight(cmd, maxW))} ${chalk100.dim(desc)}`);
|
|
47214
47306
|
}
|
|
47215
47307
|
console.log();
|
|
47216
47308
|
console.log(" " + sectionHeading("Teach NTRP"));
|
|
47217
|
-
console.log(" " +
|
|
47309
|
+
console.log(" " + chalk100.dim("NTRP learns your business over time. There are three ways to teach it:"));
|
|
47218
47310
|
const teach = [
|
|
47219
47311
|
["/remember <fact>", "Store a fact, a decision, or a preference"],
|
|
47220
47312
|
["/recall [topic]", "Show what NTRP stores about your business"],
|
|
@@ -47223,13 +47315,13 @@ function printHelp() {
|
|
|
47223
47315
|
];
|
|
47224
47316
|
const teachMaxW = Math.max(...teach.map(([c]) => c.length)) + 2;
|
|
47225
47317
|
for (const [cmd, desc] of teach) {
|
|
47226
|
-
console.log(` ${paint("accent", padRight(cmd, teachMaxW))} ${
|
|
47318
|
+
console.log(` ${paint("accent", padRight(cmd, teachMaxW))} ${chalk100.dim(desc)}`);
|
|
47227
47319
|
}
|
|
47228
|
-
console.log(" " +
|
|
47320
|
+
console.log(" " + chalk100.dim("When a key is connected, NTRP stores a small number of facts when you close a session."));
|
|
47229
47321
|
console.log();
|
|
47230
|
-
console.log(" " +
|
|
47322
|
+
console.log(" " + chalk100.dim("Factory reset: type ") + paint("accent", "/scratch") + chalk100.dim("."));
|
|
47231
47323
|
console.log();
|
|
47232
|
-
console.log(" " +
|
|
47324
|
+
console.log(" " + chalk100.dim("These commands also work: ") + paint("accent", "/new") + chalk100.dim(", ") + paint("accent", "/diagnose") + chalk100.dim(", ") + paint("accent", "/metrics") + chalk100.dim(", ") + paint("accent", "/session") + chalk100.dim("."));
|
|
47233
47325
|
console.log();
|
|
47234
47326
|
}
|
|
47235
47327
|
var REPL_BUILTINS, ANSI_PATTERN, GOODBYES, GHOST_HINTS, ghostHintTurn, activeGhostHint, suggestionPainted;
|
|
@@ -47329,7 +47421,7 @@ init_errors();
|
|
|
47329
47421
|
init_diagnostics();
|
|
47330
47422
|
init_types();
|
|
47331
47423
|
init_version();
|
|
47332
|
-
import
|
|
47424
|
+
import chalk101 from "chalk";
|
|
47333
47425
|
var VERSION = getInstalledVersion();
|
|
47334
47426
|
function exitIfVersionFlag(argv) {
|
|
47335
47427
|
const rest = argv.slice(2).filter((a) => a === "--version" || a === "-v");
|
|
@@ -47367,7 +47459,7 @@ async function main() {
|
|
|
47367
47459
|
debug: args.globals.debug
|
|
47368
47460
|
});
|
|
47369
47461
|
if (!ctx.execution.color) {
|
|
47370
|
-
|
|
47462
|
+
chalk101.level = 0;
|
|
47371
47463
|
}
|
|
47372
47464
|
fatalReporting = {
|
|
47373
47465
|
command: firstToken(args.input) || "ntrp",
|
|
@@ -47384,16 +47476,16 @@ async function main() {
|
|
|
47384
47476
|
if (isStructuredOutput(ctx.execution)) {
|
|
47385
47477
|
emitError(cmd || "ntrp", new NtrpError("license_invalid", lic.message, 3 /* Auth */));
|
|
47386
47478
|
}
|
|
47387
|
-
console.error(
|
|
47479
|
+
console.error(chalk101.red(`
|
|
47388
47480
|
${lic.message}`));
|
|
47389
|
-
console.error(
|
|
47481
|
+
console.error(chalk101.dim(" Trial's over \u2014 /upgrade and paste your key.\n"));
|
|
47390
47482
|
process.exit(1);
|
|
47391
47483
|
}
|
|
47392
47484
|
}
|
|
47393
47485
|
const PROFILE_HINT_SKIP = /* @__PURE__ */ new Set(["onboard", "setup", "config", "connect", "activate", "help", "home", "exit", "quit", "clear", "profile", "progress", "deepdive", "tour", "settings", "voice", "logs"]);
|
|
47394
47486
|
if (!isProfileConfigured() && !PROFILE_HINT_SKIP.has(cmd) && !ctx.execution.quiet) {
|
|
47395
47487
|
console.error(
|
|
47396
|
-
" " +
|
|
47488
|
+
" " + chalk101.dim("Tip: run ") + paint("accent", "ntrp") + chalk101.dim(" interactively to set up your company profile for richer answers.")
|
|
47397
47489
|
);
|
|
47398
47490
|
}
|
|
47399
47491
|
const result = await dispatch(args.input, ctx);
|
|
@@ -47405,12 +47497,12 @@ async function main() {
|
|
|
47405
47497
|
}
|
|
47406
47498
|
if (result.suggestion) {
|
|
47407
47499
|
console.error(
|
|
47408
|
-
|
|
47500
|
+
chalk101.red(` Unknown command: ${result.token}.`) + chalk101.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk101.dim("?")
|
|
47409
47501
|
);
|
|
47410
47502
|
} else {
|
|
47411
|
-
console.error(
|
|
47503
|
+
console.error(chalk101.red(` Unknown command: ${result.token}`));
|
|
47412
47504
|
}
|
|
47413
|
-
console.error(
|
|
47505
|
+
console.error(chalk101.dim(" Run 'ntrp' for the interactive prompt."));
|
|
47414
47506
|
process.exit(1);
|
|
47415
47507
|
break;
|
|
47416
47508
|
case "help":
|
|
@@ -47463,7 +47555,7 @@ async function main() {
|
|
|
47463
47555
|
if (justUpdated) {
|
|
47464
47556
|
clearTerminalHome();
|
|
47465
47557
|
console.log();
|
|
47466
|
-
console.log(" " + paint("accent", "\u2713") + " " +
|
|
47558
|
+
console.log(" " + paint("accent", "\u2713") + " " + chalk101.dim(`Now running v${justUpdated.to}`));
|
|
47467
47559
|
}
|
|
47468
47560
|
await printWelcome2(ctx, VERSION);
|
|
47469
47561
|
await runRepl(ctx, VERSION);
|
|
@@ -47477,9 +47569,9 @@ async function die(err, scope) {
|
|
|
47477
47569
|
if (fatalReporting.structured) {
|
|
47478
47570
|
emitError(fatalReporting.command, err);
|
|
47479
47571
|
}
|
|
47480
|
-
console.error(
|
|
47572
|
+
console.error(chalk101.red(` ${describeError(err)}`));
|
|
47481
47573
|
if (!(err instanceof NtrpError) && err instanceof Error && err.stack) {
|
|
47482
|
-
console.error(
|
|
47574
|
+
console.error(chalk101.dim(err.stack.split("\n").slice(1).join("\n")));
|
|
47483
47575
|
}
|
|
47484
47576
|
process.exit(err instanceof NtrpError ? err.exitCode : 1 /* RuntimeError */);
|
|
47485
47577
|
}
|
package/dist/mcp/server.js
CHANGED
|
@@ -1088,7 +1088,7 @@ import chalk3 from "chalk";
|
|
|
1088
1088
|
function printDeepdiveHint(metricId, label) {
|
|
1089
1089
|
const name = label ?? metricId;
|
|
1090
1090
|
console.log(
|
|
1091
|
-
" " + chalk3.dim(`Ask what ${name.toLowerCase()} means \u2014 or `) + paint("accent", `/tour ${metricId}`) + chalk3.dim("
|
|
1091
|
+
" " + chalk3.dim(`Ask what ${name.toLowerCase()} means \u2014 or `) + paint("accent", `/tour ${metricId}`) + chalk3.dim(" if you want the card.")
|
|
1092
1092
|
);
|
|
1093
1093
|
console.log();
|
|
1094
1094
|
}
|
|
@@ -12978,7 +12978,24 @@ function listMetricExplainers(kind) {
|
|
|
12978
12978
|
if (!kind) return METRIC_DEFINITIONS.slice();
|
|
12979
12979
|
return METRIC_DEFINITIONS.filter((m) => m.kind === kind);
|
|
12980
12980
|
}
|
|
12981
|
-
|
|
12981
|
+
function buildVitalSignsPromptBlock() {
|
|
12982
|
+
return VITAL_IDS.map((id) => {
|
|
12983
|
+
const m = getMetricExplainer(id);
|
|
12984
|
+
if (!m) {
|
|
12985
|
+
throw new Error(`buildVitalSignsPromptBlock: missing explainer for ${id}`);
|
|
12986
|
+
}
|
|
12987
|
+
if (!m.dollar_label) {
|
|
12988
|
+
throw new Error(`buildVitalSignsPromptBlock: missing dollar_label for ${id}`);
|
|
12989
|
+
}
|
|
12990
|
+
return [
|
|
12991
|
+
`- ${m.id}: ${m.tagline}`,
|
|
12992
|
+
` Teach: ${m.meaning}`,
|
|
12993
|
+
` Expert read: ${m.expert_read}`,
|
|
12994
|
+
` Dollar label: ${m.dollar_label}`
|
|
12995
|
+
].join("\n");
|
|
12996
|
+
}).join("\n");
|
|
12997
|
+
}
|
|
12998
|
+
var VITALS, SAAS, METRIC_DEFINITIONS, BY_ID, ALIAS_INDEX, VITAL_IDS, SAAS_METRIC_IDS;
|
|
12982
12999
|
var init_metric_definitions = __esm({
|
|
12983
13000
|
"src/data/metric-definitions.ts"() {
|
|
12984
13001
|
"use strict";
|
|
@@ -13772,6 +13789,13 @@ var init_metric_definitions = __esm({
|
|
|
13772
13789
|
idx.set("thread-depth", "thread_depth");
|
|
13773
13790
|
return idx;
|
|
13774
13791
|
})();
|
|
13792
|
+
VITAL_IDS = [
|
|
13793
|
+
"freshness",
|
|
13794
|
+
"flow_rate",
|
|
13795
|
+
"drop_rate",
|
|
13796
|
+
"signal_to_noise",
|
|
13797
|
+
"thread_depth"
|
|
13798
|
+
];
|
|
13775
13799
|
SAAS_METRIC_IDS = SAAS.map((m) => m.id);
|
|
13776
13800
|
}
|
|
13777
13801
|
});
|
|
@@ -15288,6 +15312,7 @@ var init_prompt_parts = __esm({
|
|
|
15288
15312
|
init_profile();
|
|
15289
15313
|
init_store();
|
|
15290
15314
|
init_gtm_counsel();
|
|
15315
|
+
init_metric_definitions();
|
|
15291
15316
|
init_playbook();
|
|
15292
15317
|
init_play_outcomes();
|
|
15293
15318
|
init_registry();
|
|
@@ -15324,16 +15349,7 @@ Restraint matters: NTRP is a stethoscope, not a surgeon. Observe, connect, and r
|
|
|
15324
15349
|
- Observe, connect, recommend \u2014 never execute CRM changes, send email, or claim an action was taken unless a tool result in this conversation confirms it.
|
|
15325
15350
|
- Weak or empty tool result: vary the arguments or approach once before concluding; if it's still empty, say what you'd need rather than filling the gap with plausible-sounding numbers.
|
|
15326
15351
|
- Never fabricate CRM records, people, companies, or dollar amounts.`;
|
|
15327
|
-
VITAL_SIGNS_BLOCK =
|
|
15328
|
-
Expert read: cut by owner and by stage first \u2014 freshness reds concentrate on people or process, rarely evenly. In a long-cycle enterprise motion 30 quiet days can be normal cadence; in a velocity motion it's a dead deal. A sudden cliff usually means a broken integration or a departed rep, not gradual decay. False positive to check: bulk-imported records nobody has touched yet.
|
|
15329
|
-
- flow_rate: Deal velocity. Low = stuck pipeline, slow progression. Dollar value = amount stuck in pipeline.
|
|
15330
|
-
Expert read: cut by stage-age, not just deal-age \u2014 find the stage where deals go to die (usually one). Compare stuck-deal age to this company's own median cycle, not a generic norm. Stuck + past-due close dates together signal happy-ears forecasting, a credibility problem before it's a revenue problem.
|
|
15331
|
-
- drop_rate: Handoff retention. Low = leads vanishing between marketing and sales. Dollar value = estimated lost revenue at handoff.
|
|
15332
|
-
Expert read: this is almost always a systems failure \u2014 routing rules, unassigned territories, dead rep queues, or a sync gap between marketing and CRM \u2014 not lazy reps. First cut by lead source; the leak usually concentrates in one or two sources. The cheapest pipeline this business can buy is the leads it already paid for.
|
|
15333
|
-
- signal_to_noise: Activity efficiency. Low = effort aimed at dead ends. Dollar value = cost of misdirected effort.
|
|
15334
|
-
Expert read: cut by rep and by account status \u2014 noise usually means reps fishing in the pond they can see (dead accounts they know) because targeting and account lists are stale. Persistent noise is a coverage-model problem, not a coaching problem. Check whether activity is logged against closed or unlinked records \u2014 often a hygiene artifact.
|
|
15335
|
-
- thread_depth: Deal resilience. Low = single-threaded deals, fragile pipeline. Dollar value = amount in single-threaded deals.
|
|
15336
|
-
Expert read: weight by deal size \u2014 one single-threaded mega-deal outweighs ten small ones. Single-threading late in the cycle is far more dangerous than early. In enterprise motions, thread depth is a leading indicator of slipped quarters: champions change jobs, and there's no second door in.`;
|
|
15352
|
+
VITAL_SIGNS_BLOCK = buildVitalSignsPromptBlock();
|
|
15337
15353
|
PLAYBOOK_BLOCK = `- "Multi-Thread Your Deals" (id: multi-thread-deals) \u2014 when thread_depth is low
|
|
15338
15354
|
- "Clean Dead Pipeline" (id: clean-dead-pipeline) \u2014 when freshness is low
|
|
15339
15355
|
- "Fix the Handoff Gap" (id: fix-handoff-gap) \u2014 when drop_rate is high and the source\u2192owner path is unknown
|
|
@@ -24654,12 +24670,9 @@ var init_ghost_hints = __esm({
|
|
|
24654
24670
|
init_suggested_asks();
|
|
24655
24671
|
PHASE_GHOST_HINTS = {
|
|
24656
24672
|
orient: [
|
|
24657
|
-
'try "pipeline health"',
|
|
24658
24673
|
'try "how healthy is the pipeline?"',
|
|
24659
|
-
'try "what
|
|
24660
|
-
'try "
|
|
24661
|
-
'try "what is the most expensive problem to solve?"',
|
|
24662
|
-
'try "board deck on Q3"'
|
|
24674
|
+
'try "what does freshness mean?"',
|
|
24675
|
+
'try "what should I do next?"'
|
|
24663
24676
|
],
|
|
24664
24677
|
awaiting_data: [
|
|
24665
24678
|
'try "use demo data"',
|