@sonnechasser/ntrp 2.2.2 → 2.4.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 +214 -109
- package/dist/mcp/server.js +41 -18
- 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(
|
|
1587
|
+
" " + chalk3.dim(`Ask what ${name.toLowerCase()} means \u2014 or `) + paint("accent", `/tour ${metricId}`) + chalk3.dim(" for the card")
|
|
1588
1588
|
);
|
|
1589
1589
|
console.log();
|
|
1590
1590
|
}
|
|
@@ -1987,6 +1987,23 @@ function printHealthSummary(result, _pipelineMetrics) {
|
|
|
1987
1987
|
VITAL_SIGN_LABELS[result.gating_vital_sign]
|
|
1988
1988
|
);
|
|
1989
1989
|
}
|
|
1990
|
+
function printHealthLine(result) {
|
|
1991
|
+
const score = `${chalk4.bold(String(Math.round(result.overall_score)))}${chalk4.dim("/100")}`;
|
|
1992
|
+
const gloss = voiceHealthGloss(result.overall_status);
|
|
1993
|
+
const parts = [
|
|
1994
|
+
`${chalk4.dim("Health")} ${score} ${statusBadge(result.overall_status)}${gloss ? chalk4.dim(` ${gloss}`) : ""}`,
|
|
1995
|
+
`${chalk4.dim("held back by")} ${paint("accent", VITAL_SIGN_LABELS[result.gating_vital_sign])}`
|
|
1996
|
+
];
|
|
1997
|
+
if (result.total_value_at_risk != null && result.total_value_at_risk > 0) {
|
|
1998
|
+
parts.push(`${paint("success", formatCurrency(result.total_value_at_risk))} ${chalk4.dim("total at risk")}`);
|
|
1999
|
+
}
|
|
2000
|
+
console.log();
|
|
2001
|
+
console.log(" " + parts.join(chalk4.dim(" \xB7 ")));
|
|
2002
|
+
printDeepdiveHint(
|
|
2003
|
+
result.gating_vital_sign,
|
|
2004
|
+
VITAL_SIGN_LABELS[result.gating_vital_sign]
|
|
2005
|
+
);
|
|
2006
|
+
}
|
|
1990
2007
|
function printVitalSigns(vitals) {
|
|
1991
2008
|
console.log();
|
|
1992
2009
|
printHeading("Vital Signs");
|
|
@@ -16931,7 +16948,7 @@ function consumeOrientEmptyEnterCoach(ctx) {
|
|
|
16931
16948
|
if (!hasValidLicense()) {
|
|
16932
16949
|
return "Type /activate to paste a key. Type /checkout if you need to sign up.";
|
|
16933
16950
|
}
|
|
16934
|
-
return "Type a question, type use demo data
|
|
16951
|
+
return "Type a question, or type use demo data. Enter alone does not start a step here.";
|
|
16935
16952
|
}
|
|
16936
16953
|
function formatPhaseLabel(phase) {
|
|
16937
16954
|
switch (phase) {
|
|
@@ -17555,7 +17572,10 @@ function buildExploreTeachingGhosts(ctx, staticExplore) {
|
|
|
17555
17572
|
if (cached2 && cached2.length > 0) {
|
|
17556
17573
|
const ghosts = asksToGhostHints(cached2);
|
|
17557
17574
|
const gating = ctx.snapshot.computeResult?.aggregate.gating_vital_sign;
|
|
17558
|
-
if (gating)
|
|
17575
|
+
if (gating) {
|
|
17576
|
+
const label = (VITAL_SIGN_LABELS[gating] ?? gating).toLowerCase();
|
|
17577
|
+
ghosts.push(`try "why is ${label} red?"`);
|
|
17578
|
+
}
|
|
17559
17579
|
ghosts.push('try "how should we fix this?"');
|
|
17560
17580
|
return dedupeGhosts(ghosts);
|
|
17561
17581
|
}
|
|
@@ -17566,7 +17586,11 @@ function buildExploreTeachingGhosts(ctx, staticExplore) {
|
|
|
17566
17586
|
});
|
|
17567
17587
|
return dedupeGhosts([
|
|
17568
17588
|
...asksToGhostHints(asks),
|
|
17569
|
-
|
|
17589
|
+
(() => {
|
|
17590
|
+
const g = health.gating_vital_sign;
|
|
17591
|
+
const label = (VITAL_SIGN_LABELS[g] ?? g).toLowerCase();
|
|
17592
|
+
return `try "why is ${label} red?"`;
|
|
17593
|
+
})(),
|
|
17570
17594
|
'try "how should we fix this?"'
|
|
17571
17595
|
]);
|
|
17572
17596
|
}
|
|
@@ -18334,7 +18358,24 @@ function listMetricExplainers(kind) {
|
|
|
18334
18358
|
function getCoreDeckExplainers() {
|
|
18335
18359
|
return CORE_DECK_IDS.map((id) => BY_ID.get(id)).filter(Boolean);
|
|
18336
18360
|
}
|
|
18337
|
-
|
|
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;
|
|
18338
18379
|
var init_metric_definitions = __esm({
|
|
18339
18380
|
"src/data/metric-definitions.ts"() {
|
|
18340
18381
|
"use strict";
|
|
@@ -19141,6 +19182,13 @@ var init_metric_definitions = __esm({
|
|
|
19141
19182
|
idx.set("thread-depth", "thread_depth");
|
|
19142
19183
|
return idx;
|
|
19143
19184
|
})();
|
|
19185
|
+
VITAL_IDS = [
|
|
19186
|
+
"freshness",
|
|
19187
|
+
"flow_rate",
|
|
19188
|
+
"drop_rate",
|
|
19189
|
+
"signal_to_noise",
|
|
19190
|
+
"thread_depth"
|
|
19191
|
+
];
|
|
19144
19192
|
SAAS_METRIC_IDS = SAAS.map((m) => m.id);
|
|
19145
19193
|
GATING_LAYER_VISUAL = {
|
|
19146
19194
|
kind: "layer_stack",
|
|
@@ -25903,8 +25951,8 @@ var init_ghost_hints = __esm({
|
|
|
25903
25951
|
PHASE_GHOST_HINTS = {
|
|
25904
25952
|
orient: [
|
|
25905
25953
|
'try "pipeline health"',
|
|
25906
|
-
|
|
25907
|
-
|
|
25954
|
+
'try "how healthy is the pipeline?"',
|
|
25955
|
+
'try "what should I do next?"',
|
|
25908
25956
|
'try "is our retention real for the board?"',
|
|
25909
25957
|
'try "what is the most expensive problem to solve?"',
|
|
25910
25958
|
'try "board deck on Q3"'
|
|
@@ -25921,7 +25969,7 @@ var init_ghost_hints = __esm({
|
|
|
25921
25969
|
'try "how should we fix this?"',
|
|
25922
25970
|
'try "which segment is weakest?"',
|
|
25923
25971
|
'try "what is ARR?"',
|
|
25924
|
-
|
|
25972
|
+
'try "why is freshness red?"',
|
|
25925
25973
|
'try "ship a board deck"'
|
|
25926
25974
|
]
|
|
25927
25975
|
};
|
|
@@ -36716,7 +36764,7 @@ async function handler19(args, ctx) {
|
|
|
36716
36764
|
console.log(chalk51.dim(` Trigger: ${triggerLabel} \u2014 ${play.trigger_condition}`));
|
|
36717
36765
|
if (play.trigger_vital_sign) {
|
|
36718
36766
|
console.log(
|
|
36719
|
-
chalk51.dim("
|
|
36767
|
+
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(" for the card")
|
|
36720
36768
|
);
|
|
36721
36769
|
}
|
|
36722
36770
|
console.log();
|
|
@@ -40446,7 +40494,8 @@ function getDeepdiveNudge(ctx) {
|
|
|
40446
40494
|
if (hasCompletedMetricsTour() || hasSeenDeepdiveHomeNudge()) return null;
|
|
40447
40495
|
if (!hasAnalysisForDeepdiveNudge(ctx)) return null;
|
|
40448
40496
|
return {
|
|
40449
|
-
text: "
|
|
40497
|
+
text: "Ask how healthy the pipeline looks",
|
|
40498
|
+
tip: "Or /tour for the numbers deck",
|
|
40450
40499
|
command: "/tour"
|
|
40451
40500
|
};
|
|
40452
40501
|
}
|
|
@@ -43034,6 +43083,7 @@ var init_prompt_parts = __esm({
|
|
|
43034
43083
|
init_profile();
|
|
43035
43084
|
init_store();
|
|
43036
43085
|
init_gtm_counsel();
|
|
43086
|
+
init_metric_definitions();
|
|
43037
43087
|
init_playbook();
|
|
43038
43088
|
init_play_outcomes();
|
|
43039
43089
|
init_registry2();
|
|
@@ -43070,16 +43120,7 @@ Restraint matters: NTRP is a stethoscope, not a surgeon. Observe, connect, and r
|
|
|
43070
43120
|
- 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.
|
|
43071
43121
|
- 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.
|
|
43072
43122
|
- Never fabricate CRM records, people, companies, or dollar amounts.`;
|
|
43073
|
-
VITAL_SIGNS_BLOCK =
|
|
43074
|
-
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.
|
|
43075
|
-
- flow_rate: Deal velocity. Low = stuck pipeline, slow progression. Dollar value = amount stuck in pipeline.
|
|
43076
|
-
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.
|
|
43077
|
-
- drop_rate: Handoff retention. Low = leads vanishing between marketing and sales. Dollar value = estimated lost revenue at handoff.
|
|
43078
|
-
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.
|
|
43079
|
-
- signal_to_noise: Activity efficiency. Low = effort aimed at dead ends. Dollar value = cost of misdirected effort.
|
|
43080
|
-
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.
|
|
43081
|
-
- thread_depth: Deal resilience. Low = single-threaded deals, fragile pipeline. Dollar value = amount in single-threaded deals.
|
|
43082
|
-
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.`;
|
|
43123
|
+
VITAL_SIGNS_BLOCK = buildVitalSignsPromptBlock();
|
|
43083
43124
|
PLAYBOOK_BLOCK = `- "Multi-Thread Your Deals" (id: multi-thread-deals) \u2014 when thread_depth is low
|
|
43084
43125
|
- "Clean Dead Pipeline" (id: clean-dead-pipeline) \u2014 when freshness is low
|
|
43085
43126
|
- "Fix the Handoff Gap" (id: fix-handoff-gap) \u2014 when drop_rate is high and the source\u2192owner path is unknown
|
|
@@ -45677,12 +45718,69 @@ var init_explore_expand = __esm({
|
|
|
45677
45718
|
}
|
|
45678
45719
|
});
|
|
45679
45720
|
|
|
45721
|
+
// src/conversation/health-chat.ts
|
|
45722
|
+
var health_chat_exports = {};
|
|
45723
|
+
__export(health_chat_exports, {
|
|
45724
|
+
isHealthChatPhase: () => isHealthChatPhase,
|
|
45725
|
+
isHealthIntent: () => isHealthIntent,
|
|
45726
|
+
tryHealthChatReadout: () => tryHealthChatReadout
|
|
45727
|
+
});
|
|
45728
|
+
import chalk94 from "chalk";
|
|
45729
|
+
function isHealthIntent(line) {
|
|
45730
|
+
const text = line.trim();
|
|
45731
|
+
if (!text) return false;
|
|
45732
|
+
if (/^(tour|\/tour|deepdive|\/deepdive)\b/i.test(text)) return false;
|
|
45733
|
+
return HEALTH_INTENT_RE.test(text);
|
|
45734
|
+
}
|
|
45735
|
+
function isHealthChatPhase(ctx) {
|
|
45736
|
+
const phase = resolveConversationPhase(ctx);
|
|
45737
|
+
return phase === "explore" || phase === "orient" && isAnalysisReady(ctx);
|
|
45738
|
+
}
|
|
45739
|
+
function tryHealthChatReadout(ctx, line) {
|
|
45740
|
+
if (!isHealthIntent(line)) return false;
|
|
45741
|
+
if (!isHealthChatPhase(ctx)) return false;
|
|
45742
|
+
const aggregate = ctx.snapshot.computeResult?.aggregate;
|
|
45743
|
+
if (!aggregate) {
|
|
45744
|
+
console.log();
|
|
45745
|
+
console.log(
|
|
45746
|
+
" " + chalk94.dim(
|
|
45747
|
+
"No health reading in this session yet. Run analysis first, then ask again."
|
|
45748
|
+
)
|
|
45749
|
+
);
|
|
45750
|
+
console.log();
|
|
45751
|
+
recordMessage(ctx, "user", line);
|
|
45752
|
+
recordMessage(ctx, "agent", "No health reading yet");
|
|
45753
|
+
saveSessionState(ctx);
|
|
45754
|
+
return true;
|
|
45755
|
+
}
|
|
45756
|
+
printHealthLine(aggregate);
|
|
45757
|
+
printVitalSigns(aggregate.vital_signs);
|
|
45758
|
+
recordMessage(ctx, "user", line);
|
|
45759
|
+
recordMessage(
|
|
45760
|
+
ctx,
|
|
45761
|
+
"agent",
|
|
45762
|
+
`Health ${Math.round(aggregate.overall_score)}/100 \xB7 gating ${aggregate.gating_vital_sign}`
|
|
45763
|
+
);
|
|
45764
|
+
saveSessionState(ctx);
|
|
45765
|
+
return true;
|
|
45766
|
+
}
|
|
45767
|
+
var HEALTH_INTENT_RE;
|
|
45768
|
+
var init_health_chat = __esm({
|
|
45769
|
+
"src/conversation/health-chat.ts"() {
|
|
45770
|
+
"use strict";
|
|
45771
|
+
init_context2();
|
|
45772
|
+
init_terminal();
|
|
45773
|
+
init_phase();
|
|
45774
|
+
HEALTH_INTENT_RE = /\b((how|how'?s|how is)\s+(healthy|the\s+pipeline|our\s+pipeline|pipeline\s+health)|pipeline\s+health|show\s+vitals|vital\s+signs?|where\s+are\s+we\s+red|where'?s\s+the\s+red|health\s+check|how\s+healthy)\b/i;
|
|
45775
|
+
}
|
|
45776
|
+
});
|
|
45777
|
+
|
|
45680
45778
|
// src/conversation/router.ts
|
|
45681
45779
|
var router_exports = {};
|
|
45682
45780
|
__export(router_exports, {
|
|
45683
45781
|
conversationRouter: () => conversationRouter
|
|
45684
45782
|
});
|
|
45685
|
-
import
|
|
45783
|
+
import chalk95 from "chalk";
|
|
45686
45784
|
function popModalState(ctx) {
|
|
45687
45785
|
const popped = [];
|
|
45688
45786
|
if (ctx.strategistState) {
|
|
@@ -45715,7 +45813,7 @@ function handleBackNavigation(ctx, line) {
|
|
|
45715
45813
|
}
|
|
45716
45814
|
if (phase === "scope") {
|
|
45717
45815
|
console.log();
|
|
45718
|
-
console.log(" " +
|
|
45816
|
+
console.log(" " + chalk95.dim("What should we focus on instead?"));
|
|
45719
45817
|
ctx.scope = void 0;
|
|
45720
45818
|
clearPendingAsk(ctx);
|
|
45721
45819
|
saveSessionState(ctx);
|
|
@@ -45735,7 +45833,7 @@ function handleBackNavigation(ctx, line) {
|
|
|
45735
45833
|
printScopeProposal(ctx);
|
|
45736
45834
|
if (hadData || hadAnalysis) {
|
|
45737
45835
|
console.log(
|
|
45738
|
-
" " +
|
|
45836
|
+
" " + chalk95.dim(
|
|
45739
45837
|
"Focus gate rewound \u2014 loaded data and any analysis stay. `b` does not unload demo data or undo compute."
|
|
45740
45838
|
)
|
|
45741
45839
|
);
|
|
@@ -45751,7 +45849,7 @@ function handleBackNavigation(ctx, line) {
|
|
|
45751
45849
|
recordMessage(ctx, "user", line);
|
|
45752
45850
|
recordMessage(ctx, "agent", "Strategy objective adjust (back)");
|
|
45753
45851
|
console.log();
|
|
45754
|
-
console.log(" " +
|
|
45852
|
+
console.log(" " + chalk95.dim("What is the objective? State a finish line."));
|
|
45755
45853
|
console.log();
|
|
45756
45854
|
return { handled: true, summary: "Awaiting objective" };
|
|
45757
45855
|
}
|
|
@@ -45763,7 +45861,7 @@ function handleBackNavigation(ctx, line) {
|
|
|
45763
45861
|
const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
|
|
45764
45862
|
console.log();
|
|
45765
45863
|
console.log(
|
|
45766
|
-
" " +
|
|
45864
|
+
" " + chalk95.dim(`Back \u2014 dropped ${popped.join(" and ")}. At `) + chalk95.cyan(backTo) + chalk95.dim(".")
|
|
45767
45865
|
);
|
|
45768
45866
|
console.log();
|
|
45769
45867
|
return { handled: true, summary: "Back" };
|
|
@@ -45777,7 +45875,7 @@ function handleBackNavigation(ctx, line) {
|
|
|
45777
45875
|
const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
|
|
45778
45876
|
console.log();
|
|
45779
45877
|
console.log(
|
|
45780
|
-
" " +
|
|
45878
|
+
" " + chalk95.dim(`Back \u2014 dropped ${popped.join(" and ")}. At `) + chalk95.cyan(backTo) + chalk95.dim(".")
|
|
45781
45879
|
);
|
|
45782
45880
|
console.log();
|
|
45783
45881
|
return { handled: true, summary: "Back" };
|
|
@@ -45821,7 +45919,7 @@ async function conversationRouter(input, ctx) {
|
|
|
45821
45919
|
if (!ok) {
|
|
45822
45920
|
console.log();
|
|
45823
45921
|
console.log(
|
|
45824
|
-
" " +
|
|
45922
|
+
" " + chalk95.dim("Staying on this session. Type ") + chalk95.cyan("/home") + chalk95.dim(" for the dashboard.")
|
|
45825
45923
|
);
|
|
45826
45924
|
console.log();
|
|
45827
45925
|
return { handled: true };
|
|
@@ -45836,7 +45934,7 @@ async function conversationRouter(input, ctx) {
|
|
|
45836
45934
|
}
|
|
45837
45935
|
console.log();
|
|
45838
45936
|
console.log(
|
|
45839
|
-
" " +
|
|
45937
|
+
" " + chalk95.dim("Start a fresh analysis with ") + chalk95.cyan("/new") + chalk95.dim(" \u2014 or ") + chalk95.cyan("/home") + chalk95.dim(" for the dashboard.")
|
|
45840
45938
|
);
|
|
45841
45939
|
console.log();
|
|
45842
45940
|
return { handled: true };
|
|
@@ -45850,7 +45948,7 @@ async function conversationRouter(input, ctx) {
|
|
|
45850
45948
|
const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
|
|
45851
45949
|
console.log();
|
|
45852
45950
|
console.log(
|
|
45853
|
-
" " +
|
|
45951
|
+
" " + chalk95.dim(`Cancelled \u2014 dropped ${popped.join(" and ")}. Back to `) + chalk95.cyan(backTo) + chalk95.dim(".")
|
|
45854
45952
|
);
|
|
45855
45953
|
console.log();
|
|
45856
45954
|
return { handled: true, summary: "Cancelled" };
|
|
@@ -45894,6 +45992,12 @@ async function conversationRouter(input, ctx) {
|
|
|
45894
45992
|
const summary = await handleKeepGoingLine(ctx, line) ?? void 0;
|
|
45895
45993
|
return { handled: true, summary };
|
|
45896
45994
|
}
|
|
45995
|
+
if (phase === "explore" || phase === "orient" && isAnalysisReady(ctx)) {
|
|
45996
|
+
const { tryHealthChatReadout: tryHealthChatReadout2 } = await Promise.resolve().then(() => (init_health_chat(), health_chat_exports));
|
|
45997
|
+
if (tryHealthChatReadout2(ctx, line)) {
|
|
45998
|
+
return { handled: true, summary: "Pipeline health" };
|
|
45999
|
+
}
|
|
46000
|
+
}
|
|
45897
46001
|
if (phase === "think") {
|
|
45898
46002
|
const summary = await handleThinkFlow(line, ctx) ?? void 0;
|
|
45899
46003
|
return { handled: true, summary };
|
|
@@ -45932,7 +46036,7 @@ async function conversationRouter(input, ctx) {
|
|
|
45932
46036
|
}
|
|
45933
46037
|
if (phase === "compute") {
|
|
45934
46038
|
console.log();
|
|
45935
|
-
console.log(" " +
|
|
46039
|
+
console.log(" " + chalk95.dim("Analysis running \u2014 wait for it to finish before typing another question."));
|
|
45936
46040
|
console.log();
|
|
45937
46041
|
return { handled: true };
|
|
45938
46042
|
}
|
|
@@ -45988,7 +46092,7 @@ __export(dispatch_exports, {
|
|
|
45988
46092
|
dispatch: () => dispatch,
|
|
45989
46093
|
replayPendingBlockedLine: () => replayPendingBlockedLine
|
|
45990
46094
|
});
|
|
45991
|
-
import
|
|
46095
|
+
import chalk96 from "chalk";
|
|
45992
46096
|
function printLicenseRequired(command) {
|
|
45993
46097
|
printLicenseBlocked(command);
|
|
45994
46098
|
}
|
|
@@ -46006,7 +46110,7 @@ async function replayPendingBlockedLine(ctx) {
|
|
|
46006
46110
|
if (!hasValidLicense()) return false;
|
|
46007
46111
|
ctx.pendingBlockedLine = void 0;
|
|
46008
46112
|
console.log();
|
|
46009
|
-
console.log(" " +
|
|
46113
|
+
console.log(" " + chalk96.dim("Picking up where you left off\u2026"));
|
|
46010
46114
|
console.log();
|
|
46011
46115
|
await dispatch(line, ctx);
|
|
46012
46116
|
return true;
|
|
@@ -46076,7 +46180,7 @@ async function dispatch(input, ctx) {
|
|
|
46076
46180
|
if (tokens.length === 1) {
|
|
46077
46181
|
if (/^\d$/.test(first)) {
|
|
46078
46182
|
console.log(
|
|
46079
|
-
" " +
|
|
46183
|
+
" " + chalk96.dim("Looks like a menu pick \u2014 run ") + paint("accent", "/new") + chalk96.dim(" to start (pick Demo, then choose your analysis type).")
|
|
46080
46184
|
);
|
|
46081
46185
|
return { kind: "handled" };
|
|
46082
46186
|
}
|
|
@@ -46099,19 +46203,19 @@ async function dispatch(input, ctx) {
|
|
|
46099
46203
|
return { kind: "handled", summary };
|
|
46100
46204
|
}
|
|
46101
46205
|
console.log(
|
|
46102
|
-
" " +
|
|
46206
|
+
" " + chalk96.dim("Not in Q&A yet. Confirm the scope, load data, and run analysis first. Type ") + paint("accent", "/home") + chalk96.dim(" for status.")
|
|
46103
46207
|
);
|
|
46104
46208
|
return { kind: "handled" };
|
|
46105
46209
|
}
|
|
46106
46210
|
console.log(
|
|
46107
|
-
" " +
|
|
46211
|
+
" " + chalk96.dim("Natural-language questions run inside ntrp. Start with ") + paint("accent", "ntrp") + chalk96.dim(" and type a question after analysis.")
|
|
46108
46212
|
);
|
|
46109
46213
|
return { kind: "handled" };
|
|
46110
46214
|
}
|
|
46111
46215
|
async function runSlashCommand(name, args, ctx) {
|
|
46112
46216
|
const handler54 = await resolveHandler(name);
|
|
46113
46217
|
if (!handler54) {
|
|
46114
|
-
console.error(
|
|
46218
|
+
console.error(chalk96.red(` Unknown command: /${name}`));
|
|
46115
46219
|
return void 0;
|
|
46116
46220
|
}
|
|
46117
46221
|
const result = await handler54(args, ctx);
|
|
@@ -46148,7 +46252,7 @@ var init_inline_suggestion = __esm({
|
|
|
46148
46252
|
});
|
|
46149
46253
|
|
|
46150
46254
|
// src/conversation/loop-guard.ts
|
|
46151
|
-
import
|
|
46255
|
+
import chalk97 from "chalk";
|
|
46152
46256
|
function createLoopGuardState() {
|
|
46153
46257
|
return { phase: null, stuckTurns: 0 };
|
|
46154
46258
|
}
|
|
@@ -46180,10 +46284,10 @@ function printLoopEscalation(phase) {
|
|
|
46180
46284
|
if (!guide) return;
|
|
46181
46285
|
console.log();
|
|
46182
46286
|
console.log(
|
|
46183
|
-
" " +
|
|
46287
|
+
" " + chalk97.yellow("We seem to be going in circles \u2014 you're in ") + paint("accent", guide.mode) + chalk97.yellow(" mode.")
|
|
46184
46288
|
);
|
|
46185
|
-
console.log(" " +
|
|
46186
|
-
console.log(" " +
|
|
46289
|
+
console.log(" " + chalk97.dim("Right now I can only accept: ") + guide.accepts);
|
|
46290
|
+
console.log(" " + chalk97.dim("To leave: ") + guide.leave);
|
|
46187
46291
|
console.log();
|
|
46188
46292
|
}
|
|
46189
46293
|
var LOOP_GUARD_THRESHOLD, MODAL_PHASES, PHASE_GUIDES;
|
|
@@ -46227,7 +46331,7 @@ __export(welcome_exports, {
|
|
|
46227
46331
|
resolveWelcomeNextAction: () => resolveWelcomeNextAction,
|
|
46228
46332
|
staleProcessHomeNotice: () => staleProcessHomeNotice
|
|
46229
46333
|
});
|
|
46230
|
-
import
|
|
46334
|
+
import chalk98 from "chalk";
|
|
46231
46335
|
function formatHomeEntityCounts(counts) {
|
|
46232
46336
|
const parts = [];
|
|
46233
46337
|
const people = counts.people ?? 0;
|
|
@@ -46241,11 +46345,11 @@ function formatHomeEntityCounts(counts) {
|
|
|
46241
46345
|
return parts.join(" \xB7 ");
|
|
46242
46346
|
}
|
|
46243
46347
|
function formatEmptyDataHomeHint(savedSessionCount, opts = {}) {
|
|
46244
|
-
const onboard = opts.includeOnboard === true ?
|
|
46348
|
+
const onboard = opts.includeOnboard === true ? chalk98.dim(", or ") + paint("accent", "/onboard") + chalk98.dim(" to calibrate") : "";
|
|
46245
46349
|
if (savedSessionCount > 0) {
|
|
46246
|
-
return
|
|
46350
|
+
return chalk98.dim("Drop a CSV or type ") + paint("accent", "use demo data") + chalk98.dim(" to load a sample") + onboard + chalk98.dim(". Type ") + paint("accent", "/session") + chalk98.dim(" to open a saved session");
|
|
46247
46351
|
}
|
|
46248
|
-
return
|
|
46352
|
+
return chalk98.dim("Drop a CSV or type ") + paint("accent", "use demo data") + chalk98.dim(" to load a sample pipeline") + onboard;
|
|
46249
46353
|
}
|
|
46250
46354
|
function staleProcessHomeNotice() {
|
|
46251
46355
|
const running = getInstalledVersion();
|
|
@@ -46287,19 +46391,19 @@ function sessionSummaryText(s) {
|
|
|
46287
46391
|
summary: s.summary,
|
|
46288
46392
|
dataset: s.dataset
|
|
46289
46393
|
});
|
|
46290
|
-
return summary === NO_SUMMARY ?
|
|
46394
|
+
return summary === NO_SUMMARY ? chalk98.dim(summary) : summary;
|
|
46291
46395
|
}
|
|
46292
46396
|
function formatLastSessionLine(s, colW, ctx, opts) {
|
|
46293
46397
|
const phase = sessionPhaseLabel(s, ctx);
|
|
46294
|
-
const current = opts?.markCurrent && s.id === ctx?.sessionId ?
|
|
46295
|
-
const meta = `${formatSessionId(s.id, s.name)} ${
|
|
46398
|
+
const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk98.dim(" \xB7 current") : "";
|
|
46399
|
+
const meta = `${formatSessionId(s.id, s.name)} ${chalk98.dim("\xB7")} ${chalk98.dim(lensBadgeLabel(s.analysis))} ${chalk98.dim("\xB7")} ${paint("accent", phase)} ${chalk98.dim("\xB7")} ${sessionSummaryText(s)}${current}`;
|
|
46296
46400
|
return truncateVisible(` ${meta}`, colW);
|
|
46297
46401
|
}
|
|
46298
46402
|
function formatActiveSessionLine(s, colW, ctx, opts) {
|
|
46299
46403
|
const indent = " ";
|
|
46300
46404
|
const idPart = formatSessionId(s.id, s.name);
|
|
46301
|
-
const status =
|
|
46302
|
-
const current = opts?.markCurrent && s.id === ctx?.sessionId ?
|
|
46405
|
+
const status = chalk98.dim(` \xB7 ${sessionStatusSuffix(s)}`);
|
|
46406
|
+
const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk98.dim(" \xB7 current") : "";
|
|
46303
46407
|
const suffix = `${status}${current}`;
|
|
46304
46408
|
const summaryBudget = Math.max(8, colW - visibleWidth(indent) - visibleWidth(idPart) - visibleWidth(suffix) - 2);
|
|
46305
46409
|
const summaryPart = truncateVisible(sessionSummaryText(s), summaryBudget);
|
|
@@ -46340,13 +46444,13 @@ function buildSystemLines(colW, statusRows, recent) {
|
|
|
46340
46444
|
lines.push(sectionHeading("System"));
|
|
46341
46445
|
const labelW = Math.max(...statusRows.map((r) => r.label.length), "last used".length);
|
|
46342
46446
|
for (const item of statusRows) {
|
|
46343
|
-
const label =
|
|
46447
|
+
const label = chalk98.dim(padRight(item.label, labelW));
|
|
46344
46448
|
const state2 = padRight(item.state, 10);
|
|
46345
46449
|
const detailW = Math.max(1, colW - labelW - 13);
|
|
46346
|
-
lines.push(`${label} ${state2} ${
|
|
46450
|
+
lines.push(`${label} ${state2} ${chalk98.dim(truncateVisible(item.detail, detailW))}`);
|
|
46347
46451
|
}
|
|
46348
46452
|
if (recent) {
|
|
46349
|
-
lines.push(`${
|
|
46453
|
+
lines.push(`${chalk98.dim(padRight("last used", labelW))} ${chalk98.dim(recent)}`);
|
|
46350
46454
|
}
|
|
46351
46455
|
return lines;
|
|
46352
46456
|
}
|
|
@@ -46354,10 +46458,10 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
|
|
|
46354
46458
|
const lines = [""];
|
|
46355
46459
|
lines.push(sectionHeading("Last Session"));
|
|
46356
46460
|
if (!lastSession) {
|
|
46357
|
-
lines.push(` ${
|
|
46461
|
+
lines.push(` ${chalk98.dim("(none)")}`);
|
|
46358
46462
|
lines.push(
|
|
46359
46463
|
truncateVisible(
|
|
46360
|
-
` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${
|
|
46464
|
+
` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${chalk98.dim(nextAction.label)} ${chalk98.dim(nextAction.detail)}`}`,
|
|
46361
46465
|
colW
|
|
46362
46466
|
)
|
|
46363
46467
|
);
|
|
@@ -46371,7 +46475,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
|
|
|
46371
46475
|
if (!isCurrent) {
|
|
46372
46476
|
lines.push(
|
|
46373
46477
|
truncateVisible(
|
|
46374
|
-
` ${
|
|
46478
|
+
` ${chalk98.dim("Resume:")} ${paint("accent", `/session ${lastSession.id.slice(-4)}`)}`,
|
|
46375
46479
|
colW
|
|
46376
46480
|
)
|
|
46377
46481
|
);
|
|
@@ -46380,7 +46484,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
|
|
|
46380
46484
|
truncateVisible(` ${actionHint(nextAction.label, nextAction.command, nextAction.detail)}`, colW)
|
|
46381
46485
|
);
|
|
46382
46486
|
} else {
|
|
46383
|
-
lines.push(truncateVisible(` ${
|
|
46487
|
+
lines.push(truncateVisible(` ${chalk98.dim(nextAction.label)} ${chalk98.dim(nextAction.detail)}`, colW));
|
|
46384
46488
|
}
|
|
46385
46489
|
if (isCurrent && emptyDataHint) {
|
|
46386
46490
|
lines.push(truncateVisible(` ${emptyDataHint}`, colW));
|
|
@@ -46391,14 +46495,14 @@ function buildActiveSessionsLines(colW, ctx, activeSessions) {
|
|
|
46391
46495
|
const lines = [""];
|
|
46392
46496
|
lines.push(sectionHeading("Active Sessions"));
|
|
46393
46497
|
if (activeSessions.length === 0) {
|
|
46394
|
-
lines.push(` ${
|
|
46498
|
+
lines.push(` ${chalk98.dim("(none in progress)")}`);
|
|
46395
46499
|
return lines;
|
|
46396
46500
|
}
|
|
46397
46501
|
for (const s of activeSessions.slice(0, 5)) {
|
|
46398
46502
|
lines.push(formatActiveSessionLine(s, colW, ctx, { markCurrent: true }));
|
|
46399
46503
|
}
|
|
46400
46504
|
if (activeSessions.length > 5) {
|
|
46401
|
-
lines.push(` ${
|
|
46505
|
+
lines.push(` ${chalk98.dim(`+${activeSessions.length - 5} more \xB7 `)}${paint("accent", "/session")}`);
|
|
46402
46506
|
}
|
|
46403
46507
|
return lines;
|
|
46404
46508
|
}
|
|
@@ -46486,7 +46590,7 @@ async function printWelcome(ctx, version) {
|
|
|
46486
46590
|
const gap = Math.max(0, innerW - versionTag.length);
|
|
46487
46591
|
const gapL = Math.floor(gap / 2);
|
|
46488
46592
|
push(
|
|
46489
|
-
border(`\u256D${"\u2500".repeat(gapL)}`) +
|
|
46593
|
+
border(`\u256D${"\u2500".repeat(gapL)}`) + chalk98.dim(versionTag) + border(`${"\u2500".repeat(gap - gapL)}\u256E`)
|
|
46490
46594
|
);
|
|
46491
46595
|
if (useWideLayout) {
|
|
46492
46596
|
const leftLines = systemLines;
|
|
@@ -46513,7 +46617,7 @@ async function printWelcome(ctx, version) {
|
|
|
46513
46617
|
push(border(`\u2570${"\u2500".repeat(innerW)}\u256F`));
|
|
46514
46618
|
push(
|
|
46515
46619
|
truncateVisible(
|
|
46516
|
-
license.valid ? ` ${paint("accent", "/help")}${
|
|
46620
|
+
license.valid ? ` ${paint("accent", "/help")}${chalk98.dim(" commands \xB7 ")}${paint("accent", "/tour")}${chalk98.dim(" tour \xB7 ")}${paint("accent", "/progress")}${chalk98.dim(" hours \xB7 ")}${paint("accent", "/session")}${chalk98.dim(" resume")}` : ` ${paint("accent", "/help")}${chalk98.dim(" commands \xB7 ")}${paint("accent", "/activate")}${chalk98.dim(" paste a key \xB7 ")}${paint("accent", "/checkout")}${chalk98.dim(" signup \xB7 ")}${paint("accent", "/progress")}${chalk98.dim(" hours")}`,
|
|
46517
46621
|
cardW
|
|
46518
46622
|
)
|
|
46519
46623
|
);
|
|
@@ -46524,14 +46628,15 @@ async function printWelcome(ctx, version) {
|
|
|
46524
46628
|
if (strategyNudge) {
|
|
46525
46629
|
push(
|
|
46526
46630
|
truncateVisible(
|
|
46527
|
-
` ${paint("warning", "\u2691")} ${
|
|
46631
|
+
` ${paint("warning", "\u2691")} ${chalk98.dim(strategyNudge.text)} ${chalk98.dim("\xB7")} ${paint("accent", strategyNudge.command)}`,
|
|
46528
46632
|
cardW
|
|
46529
46633
|
)
|
|
46530
46634
|
);
|
|
46531
46635
|
} else if (deepdiveNudge) {
|
|
46636
|
+
const tip = deepdiveNudge.tip ?? deepdiveNudge.command;
|
|
46532
46637
|
push(
|
|
46533
46638
|
truncateVisible(
|
|
46534
|
-
` ${paint("warning", "\u2691")} ${
|
|
46639
|
+
tip ? ` ${paint("warning", "\u2691")} ${chalk98.dim(deepdiveNudge.text)} ${chalk98.dim("\xB7")} ${chalk98.dim(tip)}` : ` ${paint("warning", "\u2691")} ${chalk98.dim(deepdiveNudge.text)}`,
|
|
46535
46640
|
cardW
|
|
46536
46641
|
)
|
|
46537
46642
|
);
|
|
@@ -46539,7 +46644,7 @@ async function printWelcome(ctx, version) {
|
|
|
46539
46644
|
} else if (voiceNudge) {
|
|
46540
46645
|
push(
|
|
46541
46646
|
truncateVisible(
|
|
46542
|
-
` ${paint("warning", "\u2691")} ${
|
|
46647
|
+
` ${paint("warning", "\u2691")} ${chalk98.dim(voiceNudge.text)} ${chalk98.dim("\xB7")} ${paint("accent", voiceNudge.command)}`,
|
|
46543
46648
|
cardW
|
|
46544
46649
|
)
|
|
46545
46650
|
);
|
|
@@ -46727,7 +46832,7 @@ __export(repl_exports, {
|
|
|
46727
46832
|
});
|
|
46728
46833
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
46729
46834
|
import { clearLine as clearLine2, cursorTo as cursorTo2 } from "readline";
|
|
46730
|
-
import
|
|
46835
|
+
import chalk99 from "chalk";
|
|
46731
46836
|
import { join as join42 } from "path";
|
|
46732
46837
|
function buildPrompt(ctx) {
|
|
46733
46838
|
return buildConversationPrompt(ctx);
|
|
@@ -46819,12 +46924,12 @@ function renderInlineSuggestion(rl, prompt, ctx) {
|
|
|
46819
46924
|
suggestionPainted = suffix !== null;
|
|
46820
46925
|
clearLine2(process.stdout, 0);
|
|
46821
46926
|
cursorTo2(process.stdout, 0);
|
|
46822
|
-
process.stdout.write(prompt + line + (suffix ?
|
|
46927
|
+
process.stdout.write(prompt + line + (suffix ? chalk99.dim(suffix) : ""));
|
|
46823
46928
|
cursorTo2(process.stdout, promptWidth + cursor);
|
|
46824
46929
|
}
|
|
46825
46930
|
function appendTurnLine(current, promptLabel, currentSummary) {
|
|
46826
|
-
const currentLine = currentSummary ? `${promptLabel} ${current} ${
|
|
46827
|
-
console.log(" " +
|
|
46931
|
+
const currentLine = currentSummary ? `${promptLabel} ${current} ${chalk99.white("\u2192")} ${currentSummary}` : `${promptLabel} ${current}`;
|
|
46932
|
+
console.log(" " + chalk99.dim(currentLine));
|
|
46828
46933
|
console.log();
|
|
46829
46934
|
}
|
|
46830
46935
|
async function goHome(ctx, version, history, opts) {
|
|
@@ -46834,7 +46939,7 @@ async function goHome(ctx, version, history, opts) {
|
|
|
46834
46939
|
clearTerminalHome();
|
|
46835
46940
|
if (opts?.banner) {
|
|
46836
46941
|
console.log();
|
|
46837
|
-
console.log(" " + paint("accent", "\u2713") + " " +
|
|
46942
|
+
console.log(" " + paint("accent", "\u2713") + " " + chalk99.dim(opts.banner));
|
|
46838
46943
|
}
|
|
46839
46944
|
await printWelcome(ctx, version);
|
|
46840
46945
|
}
|
|
@@ -46857,11 +46962,11 @@ async function handleDispatchResult(result, ctx, version, history) {
|
|
|
46857
46962
|
case "unknown":
|
|
46858
46963
|
if (result.suggestion) {
|
|
46859
46964
|
console.log(
|
|
46860
|
-
" " +
|
|
46965
|
+
" " + chalk99.red(`Unknown command: ${result.token}.`) + chalk99.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk99.dim("?")
|
|
46861
46966
|
);
|
|
46862
46967
|
} else {
|
|
46863
46968
|
console.log(
|
|
46864
|
-
" " +
|
|
46969
|
+
" " + chalk99.red(`Unknown command: ${result.token}`) + chalk99.dim(" Type ") + paint("accent", "/help") + chalk99.dim(" to see available commands.")
|
|
46865
46970
|
);
|
|
46866
46971
|
}
|
|
46867
46972
|
break;
|
|
@@ -46885,7 +46990,7 @@ async function runRepl(ctx, version) {
|
|
|
46885
46990
|
});
|
|
46886
46991
|
ctx.rl = rl;
|
|
46887
46992
|
console.log();
|
|
46888
|
-
console.log(" " +
|
|
46993
|
+
console.log(" " + chalk99.dim("What do you want to look at?"));
|
|
46889
46994
|
console.log();
|
|
46890
46995
|
if (ctx.pendingUpdateCheck) {
|
|
46891
46996
|
void ctx.pendingUpdateCheck.then((result) => {
|
|
@@ -46927,7 +47032,7 @@ async function runRepl(ctx, version) {
|
|
|
46927
47032
|
return;
|
|
46928
47033
|
}
|
|
46929
47034
|
sigintPrimed = true;
|
|
46930
|
-
console.log("\n " +
|
|
47035
|
+
console.log("\n " + chalk99.dim("Type /exit to quit, or press Ctrl+C again."));
|
|
46931
47036
|
};
|
|
46932
47037
|
rl.on("SIGINT", sigintHandler);
|
|
46933
47038
|
function shutdownRepl() {
|
|
@@ -46964,7 +47069,7 @@ async function runRepl(ctx, version) {
|
|
|
46964
47069
|
if (!typed && !enterAction) {
|
|
46965
47070
|
clearGhostRowAfterSubmit();
|
|
46966
47071
|
const coach = consumeOrientEmptyEnterCoach(ctx);
|
|
46967
|
-
if (coach) console.log(" " +
|
|
47072
|
+
if (coach) console.log(" " + chalk99.dim(coach));
|
|
46968
47073
|
continue;
|
|
46969
47074
|
}
|
|
46970
47075
|
const line = typed || enterAction.submit;
|
|
@@ -47015,11 +47120,11 @@ async function runRepl(ctx, version) {
|
|
|
47015
47120
|
ctx.wizardDepth = 0;
|
|
47016
47121
|
ctx.secretInputActive = false;
|
|
47017
47122
|
if (err instanceof Error && err.message === "Cancelled") {
|
|
47018
|
-
console.log(" " +
|
|
47123
|
+
console.log(" " + chalk99.dim("Cancelled."));
|
|
47019
47124
|
} else {
|
|
47020
47125
|
const { tryRecoverLlmAuthFailure: tryRecoverLlmAuthFailure2 } = await Promise.resolve().then(() => (init_auth_recovery(), auth_recovery_exports));
|
|
47021
47126
|
if (!await tryRecoverLlmAuthFailure2(ctx, err)) {
|
|
47022
|
-
console.error(" " +
|
|
47127
|
+
console.error(" " + chalk99.red("Error: " + String(err.message ?? err)));
|
|
47023
47128
|
}
|
|
47024
47129
|
}
|
|
47025
47130
|
}
|
|
@@ -47046,10 +47151,10 @@ async function runRepl(ctx, version) {
|
|
|
47046
47151
|
await closeSession(ctx);
|
|
47047
47152
|
}
|
|
47048
47153
|
if (isTranscriptActive(ctx.sessionId)) {
|
|
47049
|
-
console.log(" " +
|
|
47050
|
-
console.log(" " +
|
|
47154
|
+
console.log(" " + chalk99.dim("Transcript: ") + chalk99.dim(transcriptPathForSession(ctx.sessionId)));
|
|
47155
|
+
console.log(" " + chalk99.dim("Context brief: ") + chalk99.dim(contextDocPathForSession(ctx.sessionId)));
|
|
47051
47156
|
}
|
|
47052
|
-
console.log(" " +
|
|
47157
|
+
console.log(" " + chalk99.dim(randomGoodbye()));
|
|
47053
47158
|
}
|
|
47054
47159
|
function printHelpOneShot() {
|
|
47055
47160
|
printHelp();
|
|
@@ -47057,43 +47162,43 @@ function printHelpOneShot() {
|
|
|
47057
47162
|
function printHelp() {
|
|
47058
47163
|
console.log();
|
|
47059
47164
|
console.log(" " + sectionHeading("Conversation"));
|
|
47060
|
-
console.log(" " +
|
|
47061
|
-
console.log(" " +
|
|
47062
|
-
console.log(" " +
|
|
47063
|
-
console.log(" " +
|
|
47064
|
-
console.log(" " +
|
|
47065
|
-
console.log(" " +
|
|
47165
|
+
console.log(" " + chalk99.dim("Type the question. You do not need a slash command."));
|
|
47166
|
+
console.log(" " + chalk99.dim("Paste a CSV path or type ") + paint("accent", '"use demo data"') + chalk99.dim(" to load data."));
|
|
47167
|
+
console.log(" " + chalk99.dim("After analysis, type questions in English."));
|
|
47168
|
+
console.log(" " + chalk99.dim("Type ") + paint("accent", '"how should we fix this?"') + chalk99.dim(" to make a strategy. Type ") + paint("accent", "keep going") + chalk99.dim(" at confirm to keep working until the plan is ready."));
|
|
47169
|
+
console.log(" " + chalk99.dim("Type ") + paint("accent", '"ship a board deck"') + chalk99.dim(" to write a handoff."));
|
|
47170
|
+
console.log(" " + chalk99.dim("The ") + paint("accent", "\u203A") + chalk99.dim(" prompt shows brief or deep after analysis. Brief is the default."));
|
|
47066
47171
|
console.log();
|
|
47067
47172
|
console.log(" " + sectionHeading("Keys"));
|
|
47068
47173
|
console.log(
|
|
47069
|
-
" " + paint("accent", "\u23CE") +
|
|
47174
|
+
" " + paint("accent", "\u23CE") + chalk99.dim(
|
|
47070
47175
|
" Accepts the default. At the main prompt it runs the armed action (yes, use demo data, go ahead, /connect, /update, keep going)."
|
|
47071
47176
|
)
|
|
47072
47177
|
);
|
|
47073
47178
|
console.log(
|
|
47074
|
-
" " +
|
|
47179
|
+
" " + chalk99.dim(
|
|
47075
47180
|
" On yes/no questions and menus it accepts yes (or the recommended option). Type something else to decline or pick another path."
|
|
47076
47181
|
)
|
|
47077
47182
|
);
|
|
47078
47183
|
console.log(
|
|
47079
|
-
" " + paint("accent", "b") +
|
|
47184
|
+
" " + paint("accent", "b") + chalk99.dim(" / ") + paint("accent", "back") + chalk99.dim(" Steps back one confirm gate, or leaves a modal. Does not unload data or undo compute.")
|
|
47080
47185
|
);
|
|
47081
47186
|
console.log(
|
|
47082
|
-
" " +
|
|
47187
|
+
" " + chalk99.dim("On ") + paint("accent", "/settings") + chalk99.dim(" menus, ") + paint("accent", "b") + chalk99.dim(" leaves the hub (same as Done).")
|
|
47083
47188
|
);
|
|
47084
47189
|
console.log(
|
|
47085
|
-
" " + paint("accent", "more") +
|
|
47190
|
+
" " + paint("accent", "more") + chalk99.dim(" Shows the full strategy brief after the short summary.")
|
|
47086
47191
|
);
|
|
47087
47192
|
console.log(
|
|
47088
|
-
" " + paint("accent", "expand") +
|
|
47193
|
+
" " + paint("accent", "expand") + chalk99.dim(
|
|
47089
47194
|
" 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."
|
|
47090
47195
|
)
|
|
47091
47196
|
);
|
|
47092
47197
|
console.log(
|
|
47093
|
-
" " + paint("accent", "cancel") +
|
|
47198
|
+
" " + paint("accent", "cancel") + chalk99.dim(" Drops the current modal overlay (strategy, think, ship, unconfirmed scope).")
|
|
47094
47199
|
);
|
|
47095
47200
|
console.log(
|
|
47096
|
-
" " +
|
|
47201
|
+
" " + chalk99.dim("On ") + paint("accent", "/tour") + chalk99.dim(" slides, ") + paint("accent", "b") + chalk99.dim(" moves to the previous slide.")
|
|
47097
47202
|
);
|
|
47098
47203
|
console.log();
|
|
47099
47204
|
console.log(" " + sectionHeading("Shortcuts"));
|
|
@@ -47121,11 +47226,11 @@ function printHelp() {
|
|
|
47121
47226
|
];
|
|
47122
47227
|
const maxW = Math.max(...shortcuts.map(([c]) => c.length)) + 2;
|
|
47123
47228
|
for (const [cmd, desc] of shortcuts) {
|
|
47124
|
-
console.log(` ${paint("accent", padRight(cmd, maxW))} ${
|
|
47229
|
+
console.log(` ${paint("accent", padRight(cmd, maxW))} ${chalk99.dim(desc)}`);
|
|
47125
47230
|
}
|
|
47126
47231
|
console.log();
|
|
47127
47232
|
console.log(" " + sectionHeading("Teach NTRP"));
|
|
47128
|
-
console.log(" " +
|
|
47233
|
+
console.log(" " + chalk99.dim("NTRP learns your business over time. There are three ways to teach it:"));
|
|
47129
47234
|
const teach = [
|
|
47130
47235
|
["/remember <fact>", "Store a fact, a decision, or a preference"],
|
|
47131
47236
|
["/recall [topic]", "Show what NTRP stores about your business"],
|
|
@@ -47134,13 +47239,13 @@ function printHelp() {
|
|
|
47134
47239
|
];
|
|
47135
47240
|
const teachMaxW = Math.max(...teach.map(([c]) => c.length)) + 2;
|
|
47136
47241
|
for (const [cmd, desc] of teach) {
|
|
47137
|
-
console.log(` ${paint("accent", padRight(cmd, teachMaxW))} ${
|
|
47242
|
+
console.log(` ${paint("accent", padRight(cmd, teachMaxW))} ${chalk99.dim(desc)}`);
|
|
47138
47243
|
}
|
|
47139
|
-
console.log(" " +
|
|
47244
|
+
console.log(" " + chalk99.dim("When a key is connected, NTRP stores a small number of facts when you close a session."));
|
|
47140
47245
|
console.log();
|
|
47141
|
-
console.log(" " +
|
|
47246
|
+
console.log(" " + chalk99.dim("Factory reset: type ") + paint("accent", "/scratch") + chalk99.dim("."));
|
|
47142
47247
|
console.log();
|
|
47143
|
-
console.log(" " +
|
|
47248
|
+
console.log(" " + chalk99.dim("These commands also work: ") + paint("accent", "/new") + chalk99.dim(", ") + paint("accent", "/diagnose") + chalk99.dim(", ") + paint("accent", "/metrics") + chalk99.dim(", ") + paint("accent", "/session") + chalk99.dim("."));
|
|
47144
47249
|
console.log();
|
|
47145
47250
|
}
|
|
47146
47251
|
var REPL_BUILTINS, ANSI_PATTERN, GOODBYES, GHOST_HINTS, ghostHintTurn, activeGhostHint, suggestionPainted;
|
|
@@ -47240,7 +47345,7 @@ init_errors();
|
|
|
47240
47345
|
init_diagnostics();
|
|
47241
47346
|
init_types();
|
|
47242
47347
|
init_version();
|
|
47243
|
-
import
|
|
47348
|
+
import chalk100 from "chalk";
|
|
47244
47349
|
var VERSION = getInstalledVersion();
|
|
47245
47350
|
function exitIfVersionFlag(argv) {
|
|
47246
47351
|
const rest = argv.slice(2).filter((a) => a === "--version" || a === "-v");
|
|
@@ -47278,7 +47383,7 @@ async function main() {
|
|
|
47278
47383
|
debug: args.globals.debug
|
|
47279
47384
|
});
|
|
47280
47385
|
if (!ctx.execution.color) {
|
|
47281
|
-
|
|
47386
|
+
chalk100.level = 0;
|
|
47282
47387
|
}
|
|
47283
47388
|
fatalReporting = {
|
|
47284
47389
|
command: firstToken(args.input) || "ntrp",
|
|
@@ -47295,16 +47400,16 @@ async function main() {
|
|
|
47295
47400
|
if (isStructuredOutput(ctx.execution)) {
|
|
47296
47401
|
emitError(cmd || "ntrp", new NtrpError("license_invalid", lic.message, 3 /* Auth */));
|
|
47297
47402
|
}
|
|
47298
|
-
console.error(
|
|
47403
|
+
console.error(chalk100.red(`
|
|
47299
47404
|
${lic.message}`));
|
|
47300
|
-
console.error(
|
|
47405
|
+
console.error(chalk100.dim(" Trial's over \u2014 /upgrade and paste your key.\n"));
|
|
47301
47406
|
process.exit(1);
|
|
47302
47407
|
}
|
|
47303
47408
|
}
|
|
47304
47409
|
const PROFILE_HINT_SKIP = /* @__PURE__ */ new Set(["onboard", "setup", "config", "connect", "activate", "help", "home", "exit", "quit", "clear", "profile", "progress", "deepdive", "tour", "settings", "voice", "logs"]);
|
|
47305
47410
|
if (!isProfileConfigured() && !PROFILE_HINT_SKIP.has(cmd) && !ctx.execution.quiet) {
|
|
47306
47411
|
console.error(
|
|
47307
|
-
" " +
|
|
47412
|
+
" " + chalk100.dim("Tip: run ") + paint("accent", "ntrp") + chalk100.dim(" interactively to set up your company profile for richer answers.")
|
|
47308
47413
|
);
|
|
47309
47414
|
}
|
|
47310
47415
|
const result = await dispatch(args.input, ctx);
|
|
@@ -47316,12 +47421,12 @@ async function main() {
|
|
|
47316
47421
|
}
|
|
47317
47422
|
if (result.suggestion) {
|
|
47318
47423
|
console.error(
|
|
47319
|
-
|
|
47424
|
+
chalk100.red(` Unknown command: ${result.token}.`) + chalk100.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk100.dim("?")
|
|
47320
47425
|
);
|
|
47321
47426
|
} else {
|
|
47322
|
-
console.error(
|
|
47427
|
+
console.error(chalk100.red(` Unknown command: ${result.token}`));
|
|
47323
47428
|
}
|
|
47324
|
-
console.error(
|
|
47429
|
+
console.error(chalk100.dim(" Run 'ntrp' for the interactive prompt."));
|
|
47325
47430
|
process.exit(1);
|
|
47326
47431
|
break;
|
|
47327
47432
|
case "help":
|
|
@@ -47374,7 +47479,7 @@ async function main() {
|
|
|
47374
47479
|
if (justUpdated) {
|
|
47375
47480
|
clearTerminalHome();
|
|
47376
47481
|
console.log();
|
|
47377
|
-
console.log(" " + paint("accent", "\u2713") + " " +
|
|
47482
|
+
console.log(" " + paint("accent", "\u2713") + " " + chalk100.dim(`Now running v${justUpdated.to}`));
|
|
47378
47483
|
}
|
|
47379
47484
|
await printWelcome2(ctx, VERSION);
|
|
47380
47485
|
await runRepl(ctx, VERSION);
|
|
@@ -47388,9 +47493,9 @@ async function die(err, scope) {
|
|
|
47388
47493
|
if (fatalReporting.structured) {
|
|
47389
47494
|
emitError(fatalReporting.command, err);
|
|
47390
47495
|
}
|
|
47391
|
-
console.error(
|
|
47496
|
+
console.error(chalk100.red(` ${describeError(err)}`));
|
|
47392
47497
|
if (!(err instanceof NtrpError) && err instanceof Error && err.stack) {
|
|
47393
|
-
console.error(
|
|
47498
|
+
console.error(chalk100.dim(err.stack.split("\n").slice(1).join("\n")));
|
|
47394
47499
|
}
|
|
47395
47500
|
process.exit(err instanceof NtrpError ? err.exitCode : 1 /* RuntimeError */);
|
|
47396
47501
|
}
|
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(
|
|
1091
|
+
" " + chalk3.dim(`Ask what ${name.toLowerCase()} means \u2014 or `) + paint("accent", `/tour ${metricId}`) + chalk3.dim(" for 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
|
|
@@ -18778,7 +18794,7 @@ function consumeOrientEmptyEnterCoach(ctx) {
|
|
|
18778
18794
|
if (!hasValidLicense()) {
|
|
18779
18795
|
return "Type /activate to paste a key. Type /checkout if you need to sign up.";
|
|
18780
18796
|
}
|
|
18781
|
-
return "Type a question, type use demo data
|
|
18797
|
+
return "Type a question, or type use demo data. Enter alone does not start a step here.";
|
|
18782
18798
|
}
|
|
18783
18799
|
function formatPhaseLabel(phase) {
|
|
18784
18800
|
switch (phase) {
|
|
@@ -19698,7 +19714,10 @@ function buildExploreTeachingGhosts(ctx, staticExplore) {
|
|
|
19698
19714
|
if (cached2 && cached2.length > 0) {
|
|
19699
19715
|
const ghosts = asksToGhostHints(cached2);
|
|
19700
19716
|
const gating = ctx.snapshot.computeResult?.aggregate.gating_vital_sign;
|
|
19701
|
-
if (gating)
|
|
19717
|
+
if (gating) {
|
|
19718
|
+
const label = (VITAL_SIGN_LABELS[gating] ?? gating).toLowerCase();
|
|
19719
|
+
ghosts.push(`try "why is ${label} red?"`);
|
|
19720
|
+
}
|
|
19702
19721
|
ghosts.push('try "how should we fix this?"');
|
|
19703
19722
|
return dedupeGhosts(ghosts);
|
|
19704
19723
|
}
|
|
@@ -19709,7 +19728,11 @@ function buildExploreTeachingGhosts(ctx, staticExplore) {
|
|
|
19709
19728
|
});
|
|
19710
19729
|
return dedupeGhosts([
|
|
19711
19730
|
...asksToGhostHints(asks),
|
|
19712
|
-
|
|
19731
|
+
(() => {
|
|
19732
|
+
const g = health.gating_vital_sign;
|
|
19733
|
+
const label = (VITAL_SIGN_LABELS[g] ?? g).toLowerCase();
|
|
19734
|
+
return `try "why is ${label} red?"`;
|
|
19735
|
+
})(),
|
|
19713
19736
|
'try "how should we fix this?"'
|
|
19714
19737
|
]);
|
|
19715
19738
|
}
|
|
@@ -24648,8 +24671,8 @@ var init_ghost_hints = __esm({
|
|
|
24648
24671
|
PHASE_GHOST_HINTS = {
|
|
24649
24672
|
orient: [
|
|
24650
24673
|
'try "pipeline health"',
|
|
24651
|
-
|
|
24652
|
-
|
|
24674
|
+
'try "how healthy is the pipeline?"',
|
|
24675
|
+
'try "what should I do next?"',
|
|
24653
24676
|
'try "is our retention real for the board?"',
|
|
24654
24677
|
'try "what is the most expensive problem to solve?"',
|
|
24655
24678
|
'try "board deck on Q3"'
|
|
@@ -24666,7 +24689,7 @@ var init_ghost_hints = __esm({
|
|
|
24666
24689
|
'try "how should we fix this?"',
|
|
24667
24690
|
'try "which segment is weakest?"',
|
|
24668
24691
|
'try "what is ARR?"',
|
|
24669
|
-
|
|
24692
|
+
'try "why is freshness red?"',
|
|
24670
24693
|
'try "ship a board deck"'
|
|
24671
24694
|
]
|
|
24672
24695
|
};
|