@sonnechasser/ntrp 1.3.8 → 1.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 +1727 -761
- package/dist/mcp/server.js +831 -141
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1685,6 +1685,26 @@ function buildSessionContextDoc(file, opts = {}) {
|
|
|
1685
1685
|
if (file.strategist.origin) lines.push(`- Origin: ${file.strategist.origin}`);
|
|
1686
1686
|
lines.push("");
|
|
1687
1687
|
}
|
|
1688
|
+
if (file.think) {
|
|
1689
|
+
lines.push("## Think (in flight)");
|
|
1690
|
+
lines.push("");
|
|
1691
|
+
lines.push(`- Step: ${file.think.step}`);
|
|
1692
|
+
if (file.think.seed) lines.push(`- Seed: ${file.think.seed}`);
|
|
1693
|
+
if (file.think.origin) lines.push(`- Origin: ${file.think.origin}`);
|
|
1694
|
+
if (file.think.open_questions?.length) {
|
|
1695
|
+
lines.push("- Open questions:");
|
|
1696
|
+
for (const q of file.think.open_questions) lines.push(` - ${q}`);
|
|
1697
|
+
}
|
|
1698
|
+
if (file.think.challenged_assumptions?.length) {
|
|
1699
|
+
lines.push("- Challenged assumptions:");
|
|
1700
|
+
for (const a of file.think.challenged_assumptions) lines.push(` - ${a}`);
|
|
1701
|
+
}
|
|
1702
|
+
if (file.think.working_hypotheses?.length) {
|
|
1703
|
+
lines.push("- Working hypotheses:");
|
|
1704
|
+
for (const h of file.think.working_hypotheses) lines.push(` - ${h}`);
|
|
1705
|
+
}
|
|
1706
|
+
lines.push("");
|
|
1707
|
+
}
|
|
1688
1708
|
lines.push("## Deliverables");
|
|
1689
1709
|
lines.push("");
|
|
1690
1710
|
if (file.deliverables && file.deliverables.length > 0) {
|
|
@@ -8767,6 +8787,7 @@ function initContext(oneShot, execution) {
|
|
|
8767
8787
|
snapshot: { computeResult: null, divergences: [] },
|
|
8768
8788
|
messages: [],
|
|
8769
8789
|
conversation: [],
|
|
8790
|
+
thinkConversation: [],
|
|
8770
8791
|
stage: "new",
|
|
8771
8792
|
deliverables: [],
|
|
8772
8793
|
analysis: defaultSessionAnalysis(),
|
|
@@ -8787,12 +8808,14 @@ function buildSessionFileSnapshot(ctx) {
|
|
|
8787
8808
|
if (ctx.dataset) file.dataset = ctx.dataset;
|
|
8788
8809
|
if (ctx.deliverables.length > 0) file.deliverables = ctx.deliverables;
|
|
8789
8810
|
if (ctx.conversation.length > 0) file.thread = ctx.conversation;
|
|
8811
|
+
if (ctx.thinkConversation.length > 0) file.think_thread = ctx.thinkConversation;
|
|
8790
8812
|
if (ctx.resumedFromId) file.resumed_from = ctx.resumedFromId;
|
|
8791
8813
|
if (ctx.analysis) file.analysis = ctx.analysis;
|
|
8792
8814
|
if (ctx.scope) file.scope = ctx.scope;
|
|
8793
8815
|
if (ctx.attachments && ctx.attachments.length > 0) file.attachments = ctx.attachments;
|
|
8794
8816
|
if (ctx.llm && Object.keys(ctx.llm).length > 0) file.llm = ctx.llm;
|
|
8795
8817
|
if (ctx.strategistState) file.strategist = ctx.strategistState;
|
|
8818
|
+
if (ctx.thinkState) file.think = ctx.thinkState;
|
|
8796
8819
|
if (ctx.pendingAsk) file.pending_ask = ctx.pendingAsk;
|
|
8797
8820
|
return file;
|
|
8798
8821
|
}
|
|
@@ -8919,6 +8942,9 @@ function loadSessionFile(id) {
|
|
|
8919
8942
|
if (session.thread?.length) {
|
|
8920
8943
|
session.thread = normalizeThread(session.thread);
|
|
8921
8944
|
}
|
|
8945
|
+
if (session.think_thread?.length) {
|
|
8946
|
+
session.think_thread = normalizeThread(session.think_thread);
|
|
8947
|
+
}
|
|
8922
8948
|
return session;
|
|
8923
8949
|
} catch {
|
|
8924
8950
|
return null;
|
|
@@ -9121,6 +9147,9 @@ async function finalizeSession(ctx, stage) {
|
|
|
9121
9147
|
if (ctx.conversation.length > 0) {
|
|
9122
9148
|
file.thread = ctx.conversation;
|
|
9123
9149
|
}
|
|
9150
|
+
if (ctx.thinkConversation.length > 0) {
|
|
9151
|
+
file.think_thread = ctx.thinkConversation;
|
|
9152
|
+
}
|
|
9124
9153
|
if (ctx.analysis) {
|
|
9125
9154
|
file.analysis = ctx.analysis;
|
|
9126
9155
|
}
|
|
@@ -9136,6 +9165,9 @@ async function finalizeSession(ctx, stage) {
|
|
|
9136
9165
|
if (ctx.strategistState) {
|
|
9137
9166
|
file.strategist = ctx.strategistState;
|
|
9138
9167
|
}
|
|
9168
|
+
if (ctx.thinkState) {
|
|
9169
|
+
file.think = ctx.thinkState;
|
|
9170
|
+
}
|
|
9139
9171
|
if (ctx.pendingAsk) {
|
|
9140
9172
|
file.pending_ask = ctx.pendingAsk;
|
|
9141
9173
|
}
|
|
@@ -9197,6 +9229,7 @@ function resetContextForSwitch(ctx, opts) {
|
|
|
9197
9229
|
ctx.sessionName = opts.sessionName;
|
|
9198
9230
|
ctx.messages = opts.messages;
|
|
9199
9231
|
ctx.conversation = opts.conversation ?? [];
|
|
9232
|
+
ctx.thinkConversation = opts.thinkConversation ?? [];
|
|
9200
9233
|
ctx.resumedFromId = opts.resumedFromId;
|
|
9201
9234
|
ctx.resumedSessionSummary = opts.resumedSessionSummary;
|
|
9202
9235
|
ctx.stage = opts.stage ?? "new";
|
|
@@ -9207,6 +9240,7 @@ function resetContextForSwitch(ctx, opts) {
|
|
|
9207
9240
|
ctx.attachments = opts.attachments ?? [];
|
|
9208
9241
|
ctx.llm = opts.llm;
|
|
9209
9242
|
ctx.strategistState = opts.strategistState;
|
|
9243
|
+
ctx.thinkState = opts.thinkState;
|
|
9210
9244
|
ctx.pendingAsk = opts.pendingAsk;
|
|
9211
9245
|
ctx.gapAudit = void 0;
|
|
9212
9246
|
ctx.deliverIntent = false;
|
|
@@ -9861,10 +9895,325 @@ var init_layout = __esm({
|
|
|
9861
9895
|
}
|
|
9862
9896
|
});
|
|
9863
9897
|
|
|
9864
|
-
// src/ui/
|
|
9898
|
+
// src/ui/slides.ts
|
|
9865
9899
|
import chalk6 from "chalk";
|
|
9900
|
+
function liveFromVital(vs) {
|
|
9901
|
+
const dollarLine = vs.dollar_value != null && vs.dollar_value > 0 ? `$${vs.dollar_value >= 1e6 ? `${(vs.dollar_value / 1e6).toFixed(1)}M` : vs.dollar_value >= 1e3 ? `${(vs.dollar_value / 1e3).toFixed(0)}K` : vs.dollar_value.toFixed(0)} ${vs.dollar_label ?? ""}`.trim() : void 0;
|
|
9902
|
+
return {
|
|
9903
|
+
formatted: String(Math.round(vs.score)),
|
|
9904
|
+
status: vs.status,
|
|
9905
|
+
dollarLine
|
|
9906
|
+
};
|
|
9907
|
+
}
|
|
9908
|
+
function liveFromMetric(m) {
|
|
9909
|
+
return {
|
|
9910
|
+
formatted: m.formatted,
|
|
9911
|
+
status: m.status === "neutral" ? "neutral" : m.status,
|
|
9912
|
+
benchmarkNote: m.benchmark_note
|
|
9913
|
+
};
|
|
9914
|
+
}
|
|
9915
|
+
function clearSlideScreen() {
|
|
9916
|
+
if (process.stdout.isTTY) {
|
|
9917
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
9918
|
+
}
|
|
9919
|
+
}
|
|
9920
|
+
function slideCardWidth() {
|
|
9921
|
+
return resolveCardWidth({ min: 64, max: 100, margin: 4 });
|
|
9922
|
+
}
|
|
9923
|
+
function tonePaint(tone = "accent") {
|
|
9924
|
+
switch (tone) {
|
|
9925
|
+
case "green":
|
|
9926
|
+
return chalk6.hex("#22c55e");
|
|
9927
|
+
case "yellow":
|
|
9928
|
+
return chalk6.hex("#eab308");
|
|
9929
|
+
case "red":
|
|
9930
|
+
return chalk6.hex("#ef4444");
|
|
9931
|
+
case "neutral":
|
|
9932
|
+
return chalk6.dim;
|
|
9933
|
+
default:
|
|
9934
|
+
return (t) => paint("accent", t);
|
|
9935
|
+
}
|
|
9936
|
+
}
|
|
9937
|
+
function renderBarRow(bar, barWidth, labelW) {
|
|
9938
|
+
const fill = Math.max(0, Math.min(barWidth, Math.round(bar.value / 100 * barWidth)));
|
|
9939
|
+
const body = "\u2588".repeat(fill) + "\u2591".repeat(barWidth - fill);
|
|
9940
|
+
const colored = tonePaint(bar.tone)(body);
|
|
9941
|
+
const label = padRight(truncateVisible(bar.label, labelW), labelW);
|
|
9942
|
+
const pct = String(Math.round(bar.value)).padStart(3);
|
|
9943
|
+
return `${label} ${colored} ${chalk6.dim(pct)}`;
|
|
9944
|
+
}
|
|
9945
|
+
function renderBars(bars, inner) {
|
|
9946
|
+
const labelW = Math.min(18, Math.max(...bars.map((b) => visibleWidth(b.label)), 8));
|
|
9947
|
+
const barWidth = Math.max(8, Math.min(28, inner - labelW - 6));
|
|
9948
|
+
return bars.map((b) => renderBarRow(b, barWidth, labelW));
|
|
9949
|
+
}
|
|
9950
|
+
function renderFunnel(steps, inner) {
|
|
9951
|
+
const maxBar = Math.max(12, Math.min(40, inner - 22));
|
|
9952
|
+
const lines = [];
|
|
9953
|
+
for (const step of steps) {
|
|
9954
|
+
const w = Math.max(2, Math.round(step.widthPct / 100 * maxBar));
|
|
9955
|
+
const bar = paint("accent", "\u2588".repeat(w));
|
|
9956
|
+
const label = truncateVisible(step.label, Math.max(8, inner - maxBar - 8));
|
|
9957
|
+
lines.push(`${padRight(label, Math.min(18, inner - maxBar - 6))} ${bar} ${chalk6.dim(`${step.widthPct}%`)}`);
|
|
9958
|
+
}
|
|
9959
|
+
return lines;
|
|
9960
|
+
}
|
|
9961
|
+
function renderWaterfall(steps, inner) {
|
|
9962
|
+
const maxAbs = Math.max(...steps.map((s) => Math.abs(s.cumulative)), 1);
|
|
9963
|
+
const barW = Math.max(10, Math.min(28, inner - 28));
|
|
9964
|
+
const lines = [];
|
|
9965
|
+
for (const step of steps) {
|
|
9966
|
+
const fill = Math.max(1, Math.round(Math.abs(step.cumulative) / maxAbs * barW));
|
|
9967
|
+
const bar = step.delta >= 0 ? chalk6.hex("#22c55e")("\u2588".repeat(fill)) : chalk6.hex("#ef4444")("\u2588".repeat(fill));
|
|
9968
|
+
const deltaStr = step.delta > 0 ? `+${step.delta}` : step.delta < 0 ? `${step.delta}` : `${step.delta}`;
|
|
9969
|
+
const deltaPainted = step.delta > 0 ? chalk6.hex("#22c55e")(deltaStr.padStart(5)) : step.delta < 0 ? chalk6.hex("#ef4444")(deltaStr.padStart(5)) : chalk6.dim(deltaStr.padStart(5));
|
|
9970
|
+
const label = padRight(truncateVisible(step.label, 14), 14);
|
|
9971
|
+
lines.push(`${label} ${deltaPainted} ${bar} ${chalk6.dim(`\u2192 ${step.cumulative}`)}`);
|
|
9972
|
+
}
|
|
9973
|
+
return lines;
|
|
9974
|
+
}
|
|
9975
|
+
function renderLayerStack(layers, inner) {
|
|
9976
|
+
const lines = [];
|
|
9977
|
+
for (let i = 0; i < layers.length; i++) {
|
|
9978
|
+
const layer = layers[i];
|
|
9979
|
+
const marker2 = layer.highlight ? paint("accent", "\u25C6") : chalk6.dim("\u25C7");
|
|
9980
|
+
const text = layer.highlight ? bold(layer.label) : chalk6.dim(layer.label);
|
|
9981
|
+
lines.push(`${marker2} ${truncateVisible(text, inner - 4)}`);
|
|
9982
|
+
if (i < layers.length - 1) {
|
|
9983
|
+
lines.push(chalk6.dim(" \u2502"));
|
|
9984
|
+
}
|
|
9985
|
+
}
|
|
9986
|
+
return lines;
|
|
9987
|
+
}
|
|
9988
|
+
function renderLevers(levers, inner) {
|
|
9989
|
+
const cell = Math.floor((inner - 9) / 2);
|
|
9990
|
+
const lines = [];
|
|
9991
|
+
lines.push(chalk6.dim("\u250C" + "\u2500".repeat(Math.max(8, cell)) + "\u2510 \u250C" + "\u2500".repeat(Math.max(8, cell)) + "\u2510"));
|
|
9992
|
+
for (let i = 0; i < levers.length; i += 2) {
|
|
9993
|
+
const a = padRight(truncateVisible(levers[i] ?? "", cell - 2), cell - 2);
|
|
9994
|
+
const b = padRight(truncateVisible(levers[i + 1] ?? "", cell - 2), cell - 2);
|
|
9995
|
+
lines.push(
|
|
9996
|
+
`${paint("accent", "\u2502")} ${a} ${paint("accent", "\u2502")} ${paint("accent", "\u2502")} ${b} ${paint("accent", "\u2502")}`
|
|
9997
|
+
);
|
|
9998
|
+
}
|
|
9999
|
+
lines.push(chalk6.dim("\u2514" + "\u2500".repeat(Math.max(8, cell)) + "\u2518 \u2514" + "\u2500".repeat(Math.max(8, cell)) + "\u2518"));
|
|
10000
|
+
return lines;
|
|
10001
|
+
}
|
|
10002
|
+
function renderGauge(score, inner, status) {
|
|
10003
|
+
const st = status ?? (score >= 80 ? "green" : score >= 60 ? "yellow" : "red");
|
|
10004
|
+
const bar = scoreBar(score, st === "neutral" ? "yellow" : st, Math.min(28, inner - 12));
|
|
10005
|
+
return [`${statusDot(st)} ${bar} ${bold(String(Math.round(score)))}`];
|
|
10006
|
+
}
|
|
10007
|
+
function renderSplit(bars, inner) {
|
|
10008
|
+
if (bars.length < 2) return renderBars(bars, inner);
|
|
10009
|
+
const total = bars.reduce((s, b) => s + b.value, 0) || 100;
|
|
10010
|
+
const width = Math.max(16, Math.min(40, inner - 4));
|
|
10011
|
+
let used = 0;
|
|
10012
|
+
const parts = [];
|
|
10013
|
+
for (let i = 0; i < bars.length; i++) {
|
|
10014
|
+
const b = bars[i];
|
|
10015
|
+
const w = i === bars.length - 1 ? width - used : Math.max(1, Math.round(b.value / total * width));
|
|
10016
|
+
used += w;
|
|
10017
|
+
parts.push(tonePaint(b.tone)("\u2588".repeat(w)));
|
|
10018
|
+
}
|
|
10019
|
+
const legend = bars.map((b) => `${tonePaint(b.tone)("\u25CF")} ${b.label} ${chalk6.dim(`${Math.round(b.value)}%`)}`).join(" ");
|
|
10020
|
+
return [parts.join(""), truncateVisible(legend, inner)];
|
|
10021
|
+
}
|
|
10022
|
+
function renderVisual(visual, inner) {
|
|
10023
|
+
const lines = [];
|
|
10024
|
+
switch (visual.kind) {
|
|
10025
|
+
case "bars":
|
|
10026
|
+
if (visual.bars?.length) lines.push(...renderBars(visual.bars, inner));
|
|
10027
|
+
break;
|
|
10028
|
+
case "funnel":
|
|
10029
|
+
if (visual.funnel?.length) lines.push(...renderFunnel(visual.funnel, inner));
|
|
10030
|
+
break;
|
|
10031
|
+
case "waterfall":
|
|
10032
|
+
if (visual.waterfall?.length) lines.push(...renderWaterfall(visual.waterfall, inner));
|
|
10033
|
+
break;
|
|
10034
|
+
case "layer_stack":
|
|
10035
|
+
if (visual.layers?.length) lines.push(...renderLayerStack(visual.layers, inner));
|
|
10036
|
+
break;
|
|
10037
|
+
case "levers":
|
|
10038
|
+
if (visual.levers?.length) lines.push(...renderLevers(visual.levers, inner));
|
|
10039
|
+
break;
|
|
10040
|
+
case "gauge":
|
|
10041
|
+
lines.push(...renderGauge(visual.gauge ?? 50, inner));
|
|
10042
|
+
if (visual.bars?.length) lines.push(...renderBars(visual.bars, inner));
|
|
10043
|
+
break;
|
|
10044
|
+
case "split":
|
|
10045
|
+
if (visual.bars?.length) lines.push(...renderSplit(visual.bars, inner));
|
|
10046
|
+
break;
|
|
10047
|
+
case "none":
|
|
10048
|
+
default:
|
|
10049
|
+
break;
|
|
10050
|
+
}
|
|
10051
|
+
if (visual.caption) {
|
|
10052
|
+
lines.push(chalk6.dim(truncateVisible(visual.caption, inner)));
|
|
10053
|
+
}
|
|
10054
|
+
return lines;
|
|
10055
|
+
}
|
|
10056
|
+
function kindBadge(explainer) {
|
|
10057
|
+
if (explainer.kind === "vital") return badge("VITAL", "accent");
|
|
10058
|
+
return badge("SAAS", "info");
|
|
10059
|
+
}
|
|
10060
|
+
function statusToTone(status) {
|
|
10061
|
+
if (status === "green") return "success";
|
|
10062
|
+
if (status === "yellow") return "warning";
|
|
10063
|
+
if (status === "red") return "error";
|
|
10064
|
+
return "muted";
|
|
10065
|
+
}
|
|
10066
|
+
function pushWrapped(out, text, inner, indent = "") {
|
|
10067
|
+
for (const w of wrapWords(text, inner - indent.length)) {
|
|
10068
|
+
out.push(indent + w);
|
|
10069
|
+
}
|
|
10070
|
+
}
|
|
10071
|
+
function buildSlideContent(explainer, opts = {}) {
|
|
10072
|
+
const width = slideCardWidth();
|
|
10073
|
+
const inner = width - 4;
|
|
10074
|
+
const lines = [];
|
|
10075
|
+
const title = opts.titleOverride ?? (explainer ? explainer.label : "Metrics");
|
|
10076
|
+
if (explainer) {
|
|
10077
|
+
const headerBits = [
|
|
10078
|
+
kindBadge(explainer),
|
|
10079
|
+
chalk6.dim(explainer.group)
|
|
10080
|
+
];
|
|
10081
|
+
if (opts.index != null && opts.total != null) {
|
|
10082
|
+
headerBits.push(chalk6.dim(`slide ${opts.index}/${opts.total}`));
|
|
10083
|
+
}
|
|
10084
|
+
lines.push(headerBits.join(chalk6.dim(" \xB7 ")));
|
|
10085
|
+
lines.push(chalk6.dim(explainer.tagline));
|
|
10086
|
+
lines.push("");
|
|
10087
|
+
if (opts.live) {
|
|
10088
|
+
const live = opts.live;
|
|
10089
|
+
const tone = statusToTone(live.status);
|
|
10090
|
+
const liveLine = `${statusDot(live.status)} ${bold("Your reading:")} ${bold(live.formatted)} ` + badge(String(live.status), tone);
|
|
10091
|
+
lines.push(truncateVisible(liveLine, inner));
|
|
10092
|
+
if (live.dollarLine) {
|
|
10093
|
+
lines.push(chalk6.dim(` $ ${live.dollarLine}`));
|
|
10094
|
+
}
|
|
10095
|
+
if (live.benchmarkNote) {
|
|
10096
|
+
lines.push(chalk6.dim(` ${live.benchmarkNote}`));
|
|
10097
|
+
}
|
|
10098
|
+
lines.push("");
|
|
10099
|
+
} else {
|
|
10100
|
+
const hint = explainer.benchmarkHint?.(opts.motion);
|
|
10101
|
+
if (hint) {
|
|
10102
|
+
lines.push(chalk6.dim(`Benchmark \xB7 ${hint}`));
|
|
10103
|
+
lines.push("");
|
|
10104
|
+
}
|
|
10105
|
+
}
|
|
10106
|
+
const visual = opts.visualOverride ?? explainer.visual;
|
|
10107
|
+
const visLines = renderVisual(visual, inner);
|
|
10108
|
+
if (visLines.length) {
|
|
10109
|
+
lines.push(...visLines);
|
|
10110
|
+
lines.push("");
|
|
10111
|
+
}
|
|
10112
|
+
lines.push(sectionHeading("What it means"));
|
|
10113
|
+
pushWrapped(lines, explainer.meaning, inner, " ");
|
|
10114
|
+
lines.push("");
|
|
10115
|
+
if (!opts.skipFormula) {
|
|
10116
|
+
lines.push(sectionHeading("How it's calculated"));
|
|
10117
|
+
pushWrapped(lines, explainer.how_computed, inner, " ");
|
|
10118
|
+
for (const f of explainer.formula_lines) {
|
|
10119
|
+
lines.push(paint("accent", ` ${f}`));
|
|
10120
|
+
}
|
|
10121
|
+
lines.push("");
|
|
10122
|
+
}
|
|
10123
|
+
if (opts.deepdive) {
|
|
10124
|
+
lines.push(sectionHeading("Deep dive"));
|
|
10125
|
+
pushWrapped(lines, explainer.expert_read, inner, " ");
|
|
10126
|
+
lines.push("");
|
|
10127
|
+
for (const bullet of explainer.deepdive) {
|
|
10128
|
+
pushWrapped(lines, `\xB7 ${bullet}`, inner, " ");
|
|
10129
|
+
}
|
|
10130
|
+
if (explainer.play_id) {
|
|
10131
|
+
lines.push("");
|
|
10132
|
+
lines.push(
|
|
10133
|
+
chalk6.dim(" Play: ") + paint("accent", explainer.play_id)
|
|
10134
|
+
);
|
|
10135
|
+
}
|
|
10136
|
+
lines.push("");
|
|
10137
|
+
}
|
|
10138
|
+
} else if (opts.visualOverride) {
|
|
10139
|
+
const visLines = renderVisual(opts.visualOverride, inner);
|
|
10140
|
+
if (visLines.length) {
|
|
10141
|
+
lines.push(...visLines);
|
|
10142
|
+
lines.push("");
|
|
10143
|
+
}
|
|
10144
|
+
}
|
|
10145
|
+
if (opts.extraLines?.length) {
|
|
10146
|
+
for (const line of opts.extraLines) {
|
|
10147
|
+
if (line === "") lines.push("");
|
|
10148
|
+
else pushWrapped(lines, line, inner);
|
|
10149
|
+
}
|
|
10150
|
+
}
|
|
10151
|
+
return { title, lines, width, inner };
|
|
10152
|
+
}
|
|
10153
|
+
function renderMetricSlide(explainer, opts = {}) {
|
|
10154
|
+
const { title, lines, width, inner } = buildSlideContent(explainer, opts);
|
|
10155
|
+
const border = (s) => paint("border", s);
|
|
10156
|
+
const termW = termWidth();
|
|
10157
|
+
const outerPad = " ".repeat(Math.max(0, Math.floor((termW - width) / 2)));
|
|
10158
|
+
const out = [];
|
|
10159
|
+
out.push("");
|
|
10160
|
+
out.push(`${outerPad}${border(`\u256D${"\u2500".repeat(width - 2)}\u256E`)}`);
|
|
10161
|
+
out.push(
|
|
10162
|
+
`${outerPad}${border("\u2502 ")}${padRight(sectionHeading(title), inner)}${border(" \u2502")}`
|
|
10163
|
+
);
|
|
10164
|
+
out.push(`${outerPad}${border(`\u251C${"\u2500".repeat(width - 2)}\u2524`)}`);
|
|
10165
|
+
for (const row of lines) {
|
|
10166
|
+
out.push(
|
|
10167
|
+
`${outerPad}${border("\u2502 ")}${padRight(truncateVisible(row, inner), inner)}${border(" \u2502")}`
|
|
10168
|
+
);
|
|
10169
|
+
}
|
|
10170
|
+
const footer = opts.footer ?? (opts.deepdive ? `\u23CE next \xB7 b back \xB7 q quit` : `\u23CE next \xB7 /deepdive more \xB7 b back \xB7 q quit`);
|
|
10171
|
+
out.push(`${outerPad}${border(`\u251C${"\u2500".repeat(width - 2)}\u2524`)}`);
|
|
10172
|
+
out.push(
|
|
10173
|
+
`${outerPad}${border("\u2502 ")}${padRight(chalk6.dim(truncateVisible(footer, inner)), inner)}${border(" \u2502")}`
|
|
10174
|
+
);
|
|
10175
|
+
out.push(`${outerPad}${border(`\u2570${"\u2500".repeat(width - 2)}\u256F`)}`);
|
|
10176
|
+
out.push("");
|
|
10177
|
+
if (opts.asLines) return out;
|
|
10178
|
+
for (const line of out) console.log(line);
|
|
10179
|
+
}
|
|
10180
|
+
function progressDots(index, total) {
|
|
10181
|
+
const parts = [];
|
|
10182
|
+
for (let i = 1; i <= total; i++) {
|
|
10183
|
+
parts.push(i === index ? paint("accent", "\u25CF") : chalk6.dim("\u25CB"));
|
|
10184
|
+
}
|
|
10185
|
+
return parts.join("");
|
|
10186
|
+
}
|
|
10187
|
+
function printExplainerCatalogLine(explainer) {
|
|
10188
|
+
const kind = explainer.kind === "vital" ? paint("accent", "vital") : chalk6.dim("saas ");
|
|
10189
|
+
console.log(
|
|
10190
|
+
` ${kind} ${bold(explainer.id.padEnd(20))} ${chalk6.dim(explainer.label)} \u2014 ${chalk6.dim(explainer.tagline)}`
|
|
10191
|
+
);
|
|
10192
|
+
}
|
|
10193
|
+
function printGuideCatalogLine(slide) {
|
|
10194
|
+
console.log(
|
|
10195
|
+
` ${paint("accent", "how ")} ${bold(slide.id.padEnd(20))} ${chalk6.dim(slide.label)} \u2014 ${chalk6.dim(slide.tagline)}`
|
|
10196
|
+
);
|
|
10197
|
+
}
|
|
10198
|
+
function printDeepdiveHint(metricId, label) {
|
|
10199
|
+
const name = label ?? metricId;
|
|
10200
|
+
console.log(
|
|
10201
|
+
" " + chalk6.dim("How this number works: ") + paint("accent", `/deepdive ${metricId}`) + chalk6.dim(` \u2014 ${name}`)
|
|
10202
|
+
);
|
|
10203
|
+
console.log();
|
|
10204
|
+
}
|
|
10205
|
+
var init_slides = __esm({
|
|
10206
|
+
"src/ui/slides.ts"() {
|
|
10207
|
+
"use strict";
|
|
10208
|
+
init_theme();
|
|
10209
|
+
init_layout();
|
|
10210
|
+
}
|
|
10211
|
+
});
|
|
10212
|
+
|
|
10213
|
+
// src/ui/banner.ts
|
|
10214
|
+
import chalk7 from "chalk";
|
|
9866
10215
|
function renderLogo() {
|
|
9867
|
-
return LOGO_LINES.map((line, i) =>
|
|
10216
|
+
return LOGO_LINES.map((line, i) => chalk7.hex(GRADIENT[i % GRADIENT.length])(line));
|
|
9868
10217
|
}
|
|
9869
10218
|
function printCenteredLogo() {
|
|
9870
10219
|
const width = termWidth();
|
|
@@ -9890,7 +10239,7 @@ function printReplHeader(version) {
|
|
|
9890
10239
|
const gap = Math.max(0, innerW - versionTag.length);
|
|
9891
10240
|
const gapL = Math.floor(gap / 2);
|
|
9892
10241
|
console.log(
|
|
9893
|
-
outerPad + paint("border", `\u256D${"\u2500".repeat(gapL)}`) +
|
|
10242
|
+
outerPad + paint("border", `\u256D${"\u2500".repeat(gapL)}`) + chalk7.dim(versionTag) + paint("border", `${"\u2500".repeat(gap - gapL)}\u256E`)
|
|
9894
10243
|
);
|
|
9895
10244
|
console.log();
|
|
9896
10245
|
}
|
|
@@ -10434,7 +10783,7 @@ __export(upgrade_exports, {
|
|
|
10434
10783
|
resolveUpgradeReason: () => resolveUpgradeReason,
|
|
10435
10784
|
runUpgradeFlow: () => runUpgradeFlow
|
|
10436
10785
|
});
|
|
10437
|
-
import
|
|
10786
|
+
import chalk8 from "chalk";
|
|
10438
10787
|
function checkoutUrlFor(purpose) {
|
|
10439
10788
|
return purpose === "upgrade" ? getUpgradeUrl() : getCheckoutUrl();
|
|
10440
10789
|
}
|
|
@@ -10448,25 +10797,25 @@ function printLicenseBlocked(context) {
|
|
|
10448
10797
|
const lic = checkLicense();
|
|
10449
10798
|
console.log();
|
|
10450
10799
|
if (isTrialCutoff(lic)) {
|
|
10451
|
-
console.log(" " +
|
|
10800
|
+
console.log(" " + chalk8.yellow(randomBlockedNudge()));
|
|
10452
10801
|
} else {
|
|
10453
|
-
console.log(
|
|
10802
|
+
console.log(chalk8.red(` A license is required for ${context}.`));
|
|
10454
10803
|
console.log(
|
|
10455
|
-
" " +
|
|
10804
|
+
" " + chalk8.dim("Type ") + paint("accent", "/activate") + chalk8.dim(" to paste a key, or ") + paint("accent", "/checkout") + chalk8.dim(" to sign up.")
|
|
10456
10805
|
);
|
|
10457
10806
|
}
|
|
10458
10807
|
console.log();
|
|
10459
10808
|
}
|
|
10460
10809
|
function printGraceNudge(lic) {
|
|
10461
10810
|
if (!lic.shouldNudgeUpgrade || lic.daysUntilLockout === void 0) return;
|
|
10462
|
-
console.log(" " +
|
|
10811
|
+
console.log(" " + chalk8.yellow(randomGraceNudge(lic.daysUntilLockout)));
|
|
10463
10812
|
console.log();
|
|
10464
10813
|
}
|
|
10465
10814
|
function printActiveTrialNudge(lic) {
|
|
10466
10815
|
if (!lic.shouldNudgeUpgrade || lic.trialPhase !== "active") return;
|
|
10467
10816
|
const daysLeft = lic.trialDaysRemaining;
|
|
10468
10817
|
if (daysLeft === void 0 || daysLeft <= 0) return;
|
|
10469
|
-
console.log(" " +
|
|
10818
|
+
console.log(" " + chalk8.yellow(randomActiveTrialNudge(daysLeft)));
|
|
10470
10819
|
console.log();
|
|
10471
10820
|
}
|
|
10472
10821
|
function printTrialNudge(lic) {
|
|
@@ -10487,7 +10836,7 @@ function subtitleFor(reason) {
|
|
|
10487
10836
|
}
|
|
10488
10837
|
async function promptOpenCheckout(ctx, purpose = "signup") {
|
|
10489
10838
|
const url = checkoutUrlFor(purpose);
|
|
10490
|
-
console.log(" " +
|
|
10839
|
+
console.log(" " + chalk8.dim(url));
|
|
10491
10840
|
if (!process.stdin.isTTY || process.env.NTRP_NO_BROWSER_OPEN === "1") {
|
|
10492
10841
|
console.log();
|
|
10493
10842
|
return;
|
|
@@ -10498,14 +10847,14 @@ async function promptOpenCheckout(ctx, purpose = "signup") {
|
|
|
10498
10847
|
await session.askPressEnter("Open checkout in your browser");
|
|
10499
10848
|
try {
|
|
10500
10849
|
await openInBrowser(url);
|
|
10501
|
-
console.log(" " +
|
|
10850
|
+
console.log(" " + chalk8.green("\u2713 Browser opened"));
|
|
10502
10851
|
console.log(
|
|
10503
|
-
" " +
|
|
10852
|
+
" " + chalk8.dim(
|
|
10504
10853
|
purpose === "upgrade" ? "Complete checkout in your browser. Then paste your Pro key below." : "Complete signup in your browser. Then paste your key below."
|
|
10505
10854
|
)
|
|
10506
10855
|
);
|
|
10507
10856
|
} catch {
|
|
10508
|
-
console.log(" " +
|
|
10857
|
+
console.log(" " + chalk8.yellow("Could not open the browser. Copy the URL above."));
|
|
10509
10858
|
}
|
|
10510
10859
|
console.log();
|
|
10511
10860
|
} finally {
|
|
@@ -10515,18 +10864,18 @@ async function promptOpenCheckout(ctx, purpose = "signup") {
|
|
|
10515
10864
|
async function openCheckoutInBrowser() {
|
|
10516
10865
|
const url = getCheckoutUrl();
|
|
10517
10866
|
console.log();
|
|
10518
|
-
console.log(" " +
|
|
10867
|
+
console.log(" " + chalk8.dim(url));
|
|
10519
10868
|
if (!process.stdin.isTTY) {
|
|
10520
10869
|
console.log();
|
|
10521
10870
|
return;
|
|
10522
10871
|
}
|
|
10523
10872
|
try {
|
|
10524
10873
|
await openInBrowser(url);
|
|
10525
|
-
console.log(" " +
|
|
10874
|
+
console.log(" " + chalk8.green("\u2713 Browser opened"));
|
|
10526
10875
|
} catch {
|
|
10527
|
-
console.log(" " +
|
|
10876
|
+
console.log(" " + chalk8.yellow("Could not open the browser. Copy the URL above."));
|
|
10528
10877
|
}
|
|
10529
|
-
console.log(" " +
|
|
10878
|
+
console.log(" " + chalk8.dim("After signup, paste your key with /activate or /upgrade."));
|
|
10530
10879
|
console.log();
|
|
10531
10880
|
}
|
|
10532
10881
|
async function promptForLicenseKey(ctx, purpose = "signup") {
|
|
@@ -10538,13 +10887,13 @@ async function promptForLicenseKey(ctx, purpose = "signup") {
|
|
|
10538
10887
|
key = await session.askSecret("Paste your license key", { confirm: false });
|
|
10539
10888
|
} catch (err) {
|
|
10540
10889
|
if (err instanceof Error && err.message === "Cancelled") {
|
|
10541
|
-
console.log(" " +
|
|
10890
|
+
console.log(" " + chalk8.dim("Activation cancelled."));
|
|
10542
10891
|
return false;
|
|
10543
10892
|
}
|
|
10544
10893
|
throw err;
|
|
10545
10894
|
}
|
|
10546
10895
|
if (!key.trim()) {
|
|
10547
|
-
console.log(" " +
|
|
10896
|
+
console.log(" " + chalk8.red("A license key is required."));
|
|
10548
10897
|
continue;
|
|
10549
10898
|
}
|
|
10550
10899
|
let result;
|
|
@@ -10552,21 +10901,21 @@ async function promptForLicenseKey(ctx, purpose = "signup") {
|
|
|
10552
10901
|
result = await activateLicenseKey(key.trim());
|
|
10553
10902
|
} catch (err) {
|
|
10554
10903
|
const message = err instanceof Error ? err.message : "License activation failed";
|
|
10555
|
-
console.log(" " +
|
|
10556
|
-
console.log(" " +
|
|
10904
|
+
console.log(" " + chalk8.red(message));
|
|
10905
|
+
console.log(" " + chalk8.dim("Check your network connection and try again."));
|
|
10557
10906
|
console.log();
|
|
10558
10907
|
continue;
|
|
10559
10908
|
}
|
|
10560
10909
|
if (!result.valid) {
|
|
10561
|
-
console.log(" " +
|
|
10910
|
+
console.log(" " + chalk8.red(result.message));
|
|
10562
10911
|
console.log(
|
|
10563
|
-
" " +
|
|
10912
|
+
" " + chalk8.dim(`Use the key from your purchase email, or try again: ${checkoutUrlFor(purpose)}`)
|
|
10564
10913
|
);
|
|
10565
10914
|
console.log();
|
|
10566
10915
|
continue;
|
|
10567
10916
|
}
|
|
10568
10917
|
console.log();
|
|
10569
|
-
console.log(
|
|
10918
|
+
console.log(chalk8.green(` \u2713 ${randomProActivatedLine()}`));
|
|
10570
10919
|
console.log();
|
|
10571
10920
|
return true;
|
|
10572
10921
|
}
|
|
@@ -10578,10 +10927,10 @@ async function runUpgradeFlow(ctx, reason) {
|
|
|
10578
10927
|
const lic = checkLicense();
|
|
10579
10928
|
printCenteredLogo();
|
|
10580
10929
|
console.log(" " + bold(headlineFor(reason, lic)));
|
|
10581
|
-
console.log(" " +
|
|
10930
|
+
console.log(" " + chalk8.dim(subtitleFor(reason)));
|
|
10582
10931
|
console.log();
|
|
10583
10932
|
await promptOpenCheckout(ctx, "upgrade");
|
|
10584
|
-
console.log(" " +
|
|
10933
|
+
console.log(" " + chalk8.dim("Paste your license key when it arrives by email."));
|
|
10585
10934
|
console.log();
|
|
10586
10935
|
return promptForLicenseKey(ctx, "upgrade");
|
|
10587
10936
|
}
|
|
@@ -10609,7 +10958,7 @@ var init_upgrade = __esm({
|
|
|
10609
10958
|
});
|
|
10610
10959
|
|
|
10611
10960
|
// src/license/activation.ts
|
|
10612
|
-
import
|
|
10961
|
+
import chalk9 from "chalk";
|
|
10613
10962
|
function hasValidLicense() {
|
|
10614
10963
|
return checkLicense().valid;
|
|
10615
10964
|
}
|
|
@@ -10617,10 +10966,10 @@ async function ensureLicenseActivated(ctx, options = {}) {
|
|
|
10617
10966
|
if (hasValidLicense()) return false;
|
|
10618
10967
|
if (!process.stdin.isTTY) {
|
|
10619
10968
|
console.error();
|
|
10620
|
-
console.error(
|
|
10621
|
-
console.error(
|
|
10622
|
-
console.error(
|
|
10623
|
-
console.error(
|
|
10969
|
+
console.error(chalk9.red(" A license key is required."));
|
|
10970
|
+
console.error(chalk9.dim(` Sign up: ${getCheckoutUrl()}`));
|
|
10971
|
+
console.error(chalk9.dim(" Then type: ntrp activate <key>"));
|
|
10972
|
+
console.error(chalk9.dim(" Or set NTRP_LICENSE_KEY for headless use."));
|
|
10624
10973
|
console.error();
|
|
10625
10974
|
process.exit(1);
|
|
10626
10975
|
}
|
|
@@ -10637,9 +10986,9 @@ async function ensureLicenseActivated(ctx, options = {}) {
|
|
|
10637
10986
|
}
|
|
10638
10987
|
printCenteredLogo();
|
|
10639
10988
|
console.log(" " + bold("Welcome to NTRP"));
|
|
10640
|
-
console.log(" " +
|
|
10641
|
-
console.log(" " +
|
|
10642
|
-
console.log(" " +
|
|
10989
|
+
console.log(" " + chalk9.dim(TAGLINE));
|
|
10990
|
+
console.log(" " + chalk9.dim("Paste a trial key or a Pro key. If you do not have a key, NTRP opens signup."));
|
|
10991
|
+
console.log(" " + chalk9.dim("Activating accepts the NTRP license (LICENSE in the install, or ntrp.sonnechasser.com)."));
|
|
10643
10992
|
console.log();
|
|
10644
10993
|
await promptOpenCheckout(ctx);
|
|
10645
10994
|
const activated = await promptForLicenseKey(ctx);
|
|
@@ -10651,12 +11000,14 @@ async function ensureLicenseActivated(ctx, options = {}) {
|
|
|
10651
11000
|
return true;
|
|
10652
11001
|
}
|
|
10653
11002
|
function exitActivationCancelled() {
|
|
10654
|
-
console.log(" " +
|
|
11003
|
+
console.log(" " + chalk9.dim("No license activated. Type ") + chalk9.cyan("ntrp") + chalk9.dim(" to try again."));
|
|
10655
11004
|
console.log();
|
|
10656
11005
|
process.exit(130);
|
|
10657
11006
|
}
|
|
10658
11007
|
function printActivationCancelledStay() {
|
|
10659
|
-
console.log(
|
|
11008
|
+
console.log(
|
|
11009
|
+
" " + chalk9.dim("No license activated. Type ") + chalk9.cyan("/activate") + chalk9.dim(" to paste a key. Type ") + chalk9.cyan("/checkout") + chalk9.dim(" if you need to sign up.")
|
|
11010
|
+
);
|
|
10660
11011
|
console.log();
|
|
10661
11012
|
}
|
|
10662
11013
|
var init_activation = __esm({
|
|
@@ -11976,326 +12327,12 @@ var init_guide_slides = __esm({
|
|
|
11976
12327
|
}
|
|
11977
12328
|
});
|
|
11978
12329
|
|
|
11979
|
-
// src/ui/slides.ts
|
|
11980
|
-
import chalk9 from "chalk";
|
|
11981
|
-
function liveFromVital(vs) {
|
|
11982
|
-
const dollarLine = vs.dollar_value != null && vs.dollar_value > 0 ? `$${vs.dollar_value >= 1e6 ? `${(vs.dollar_value / 1e6).toFixed(1)}M` : vs.dollar_value >= 1e3 ? `${(vs.dollar_value / 1e3).toFixed(0)}K` : vs.dollar_value.toFixed(0)} ${vs.dollar_label ?? ""}`.trim() : void 0;
|
|
11983
|
-
return {
|
|
11984
|
-
formatted: String(Math.round(vs.score)),
|
|
11985
|
-
status: vs.status,
|
|
11986
|
-
dollarLine
|
|
11987
|
-
};
|
|
11988
|
-
}
|
|
11989
|
-
function liveFromMetric(m) {
|
|
11990
|
-
return {
|
|
11991
|
-
formatted: m.formatted,
|
|
11992
|
-
status: m.status === "neutral" ? "neutral" : m.status,
|
|
11993
|
-
benchmarkNote: m.benchmark_note
|
|
11994
|
-
};
|
|
11995
|
-
}
|
|
11996
|
-
function clearSlideScreen() {
|
|
11997
|
-
if (process.stdout.isTTY) {
|
|
11998
|
-
process.stdout.write("\x1B[2J\x1B[H");
|
|
11999
|
-
}
|
|
12000
|
-
}
|
|
12001
|
-
function slideCardWidth() {
|
|
12002
|
-
return resolveCardWidth({ min: 64, max: 100, margin: 4 });
|
|
12003
|
-
}
|
|
12004
|
-
function tonePaint(tone = "accent") {
|
|
12005
|
-
switch (tone) {
|
|
12006
|
-
case "green":
|
|
12007
|
-
return chalk9.hex("#22c55e");
|
|
12008
|
-
case "yellow":
|
|
12009
|
-
return chalk9.hex("#eab308");
|
|
12010
|
-
case "red":
|
|
12011
|
-
return chalk9.hex("#ef4444");
|
|
12012
|
-
case "neutral":
|
|
12013
|
-
return chalk9.dim;
|
|
12014
|
-
default:
|
|
12015
|
-
return (t) => paint("accent", t);
|
|
12016
|
-
}
|
|
12017
|
-
}
|
|
12018
|
-
function renderBarRow(bar, barWidth, labelW) {
|
|
12019
|
-
const fill = Math.max(0, Math.min(barWidth, Math.round(bar.value / 100 * barWidth)));
|
|
12020
|
-
const body = "\u2588".repeat(fill) + "\u2591".repeat(barWidth - fill);
|
|
12021
|
-
const colored = tonePaint(bar.tone)(body);
|
|
12022
|
-
const label = padRight(truncateVisible(bar.label, labelW), labelW);
|
|
12023
|
-
const pct = String(Math.round(bar.value)).padStart(3);
|
|
12024
|
-
return `${label} ${colored} ${chalk9.dim(pct)}`;
|
|
12025
|
-
}
|
|
12026
|
-
function renderBars(bars, inner) {
|
|
12027
|
-
const labelW = Math.min(18, Math.max(...bars.map((b) => visibleWidth(b.label)), 8));
|
|
12028
|
-
const barWidth = Math.max(8, Math.min(28, inner - labelW - 6));
|
|
12029
|
-
return bars.map((b) => renderBarRow(b, barWidth, labelW));
|
|
12030
|
-
}
|
|
12031
|
-
function renderFunnel(steps, inner) {
|
|
12032
|
-
const maxBar = Math.max(12, Math.min(40, inner - 22));
|
|
12033
|
-
const lines = [];
|
|
12034
|
-
for (const step of steps) {
|
|
12035
|
-
const w = Math.max(2, Math.round(step.widthPct / 100 * maxBar));
|
|
12036
|
-
const bar = paint("accent", "\u2588".repeat(w));
|
|
12037
|
-
const label = truncateVisible(step.label, Math.max(8, inner - maxBar - 8));
|
|
12038
|
-
lines.push(`${padRight(label, Math.min(18, inner - maxBar - 6))} ${bar} ${chalk9.dim(`${step.widthPct}%`)}`);
|
|
12039
|
-
}
|
|
12040
|
-
return lines;
|
|
12041
|
-
}
|
|
12042
|
-
function renderWaterfall(steps, inner) {
|
|
12043
|
-
const maxAbs = Math.max(...steps.map((s) => Math.abs(s.cumulative)), 1);
|
|
12044
|
-
const barW = Math.max(10, Math.min(28, inner - 28));
|
|
12045
|
-
const lines = [];
|
|
12046
|
-
for (const step of steps) {
|
|
12047
|
-
const fill = Math.max(1, Math.round(Math.abs(step.cumulative) / maxAbs * barW));
|
|
12048
|
-
const bar = step.delta >= 0 ? chalk9.hex("#22c55e")("\u2588".repeat(fill)) : chalk9.hex("#ef4444")("\u2588".repeat(fill));
|
|
12049
|
-
const deltaStr = step.delta > 0 ? `+${step.delta}` : step.delta < 0 ? `${step.delta}` : `${step.delta}`;
|
|
12050
|
-
const deltaPainted = step.delta > 0 ? chalk9.hex("#22c55e")(deltaStr.padStart(5)) : step.delta < 0 ? chalk9.hex("#ef4444")(deltaStr.padStart(5)) : chalk9.dim(deltaStr.padStart(5));
|
|
12051
|
-
const label = padRight(truncateVisible(step.label, 14), 14);
|
|
12052
|
-
lines.push(`${label} ${deltaPainted} ${bar} ${chalk9.dim(`\u2192 ${step.cumulative}`)}`);
|
|
12053
|
-
}
|
|
12054
|
-
return lines;
|
|
12055
|
-
}
|
|
12056
|
-
function renderLayerStack(layers, inner) {
|
|
12057
|
-
const lines = [];
|
|
12058
|
-
for (let i = 0; i < layers.length; i++) {
|
|
12059
|
-
const layer = layers[i];
|
|
12060
|
-
const marker2 = layer.highlight ? paint("accent", "\u25C6") : chalk9.dim("\u25C7");
|
|
12061
|
-
const text = layer.highlight ? bold(layer.label) : chalk9.dim(layer.label);
|
|
12062
|
-
lines.push(`${marker2} ${truncateVisible(text, inner - 4)}`);
|
|
12063
|
-
if (i < layers.length - 1) {
|
|
12064
|
-
lines.push(chalk9.dim(" \u2502"));
|
|
12065
|
-
}
|
|
12066
|
-
}
|
|
12067
|
-
return lines;
|
|
12068
|
-
}
|
|
12069
|
-
function renderLevers(levers, inner) {
|
|
12070
|
-
const cell = Math.floor((inner - 9) / 2);
|
|
12071
|
-
const lines = [];
|
|
12072
|
-
lines.push(chalk9.dim("\u250C" + "\u2500".repeat(Math.max(8, cell)) + "\u2510 \u250C" + "\u2500".repeat(Math.max(8, cell)) + "\u2510"));
|
|
12073
|
-
for (let i = 0; i < levers.length; i += 2) {
|
|
12074
|
-
const a = padRight(truncateVisible(levers[i] ?? "", cell - 2), cell - 2);
|
|
12075
|
-
const b = padRight(truncateVisible(levers[i + 1] ?? "", cell - 2), cell - 2);
|
|
12076
|
-
lines.push(
|
|
12077
|
-
`${paint("accent", "\u2502")} ${a} ${paint("accent", "\u2502")} ${paint("accent", "\u2502")} ${b} ${paint("accent", "\u2502")}`
|
|
12078
|
-
);
|
|
12079
|
-
}
|
|
12080
|
-
lines.push(chalk9.dim("\u2514" + "\u2500".repeat(Math.max(8, cell)) + "\u2518 \u2514" + "\u2500".repeat(Math.max(8, cell)) + "\u2518"));
|
|
12081
|
-
return lines;
|
|
12082
|
-
}
|
|
12083
|
-
function renderGauge(score, inner, status) {
|
|
12084
|
-
const st = status ?? (score >= 80 ? "green" : score >= 60 ? "yellow" : "red");
|
|
12085
|
-
const bar = scoreBar(score, st === "neutral" ? "yellow" : st, Math.min(28, inner - 12));
|
|
12086
|
-
return [`${statusDot(st)} ${bar} ${bold(String(Math.round(score)))}`];
|
|
12087
|
-
}
|
|
12088
|
-
function renderSplit(bars, inner) {
|
|
12089
|
-
if (bars.length < 2) return renderBars(bars, inner);
|
|
12090
|
-
const total = bars.reduce((s, b) => s + b.value, 0) || 100;
|
|
12091
|
-
const width = Math.max(16, Math.min(40, inner - 4));
|
|
12092
|
-
let used = 0;
|
|
12093
|
-
const parts = [];
|
|
12094
|
-
for (let i = 0; i < bars.length; i++) {
|
|
12095
|
-
const b = bars[i];
|
|
12096
|
-
const w = i === bars.length - 1 ? width - used : Math.max(1, Math.round(b.value / total * width));
|
|
12097
|
-
used += w;
|
|
12098
|
-
parts.push(tonePaint(b.tone)("\u2588".repeat(w)));
|
|
12099
|
-
}
|
|
12100
|
-
const legend = bars.map((b) => `${tonePaint(b.tone)("\u25CF")} ${b.label} ${chalk9.dim(`${Math.round(b.value)}%`)}`).join(" ");
|
|
12101
|
-
return [parts.join(""), truncateVisible(legend, inner)];
|
|
12102
|
-
}
|
|
12103
|
-
function renderVisual(visual, inner) {
|
|
12104
|
-
const lines = [];
|
|
12105
|
-
switch (visual.kind) {
|
|
12106
|
-
case "bars":
|
|
12107
|
-
if (visual.bars?.length) lines.push(...renderBars(visual.bars, inner));
|
|
12108
|
-
break;
|
|
12109
|
-
case "funnel":
|
|
12110
|
-
if (visual.funnel?.length) lines.push(...renderFunnel(visual.funnel, inner));
|
|
12111
|
-
break;
|
|
12112
|
-
case "waterfall":
|
|
12113
|
-
if (visual.waterfall?.length) lines.push(...renderWaterfall(visual.waterfall, inner));
|
|
12114
|
-
break;
|
|
12115
|
-
case "layer_stack":
|
|
12116
|
-
if (visual.layers?.length) lines.push(...renderLayerStack(visual.layers, inner));
|
|
12117
|
-
break;
|
|
12118
|
-
case "levers":
|
|
12119
|
-
if (visual.levers?.length) lines.push(...renderLevers(visual.levers, inner));
|
|
12120
|
-
break;
|
|
12121
|
-
case "gauge":
|
|
12122
|
-
lines.push(...renderGauge(visual.gauge ?? 50, inner));
|
|
12123
|
-
if (visual.bars?.length) lines.push(...renderBars(visual.bars, inner));
|
|
12124
|
-
break;
|
|
12125
|
-
case "split":
|
|
12126
|
-
if (visual.bars?.length) lines.push(...renderSplit(visual.bars, inner));
|
|
12127
|
-
break;
|
|
12128
|
-
case "none":
|
|
12129
|
-
default:
|
|
12130
|
-
break;
|
|
12131
|
-
}
|
|
12132
|
-
if (visual.caption) {
|
|
12133
|
-
lines.push(chalk9.dim(truncateVisible(visual.caption, inner)));
|
|
12134
|
-
}
|
|
12135
|
-
return lines;
|
|
12136
|
-
}
|
|
12137
|
-
function kindBadge(explainer) {
|
|
12138
|
-
if (explainer.kind === "vital") return badge("VITAL", "accent");
|
|
12139
|
-
return badge("SAAS", "info");
|
|
12140
|
-
}
|
|
12141
|
-
function statusToTone(status) {
|
|
12142
|
-
if (status === "green") return "success";
|
|
12143
|
-
if (status === "yellow") return "warning";
|
|
12144
|
-
if (status === "red") return "error";
|
|
12145
|
-
return "muted";
|
|
12146
|
-
}
|
|
12147
|
-
function pushWrapped(out, text, inner, indent = "") {
|
|
12148
|
-
for (const w of wrapWords(text, inner - indent.length)) {
|
|
12149
|
-
out.push(indent + w);
|
|
12150
|
-
}
|
|
12151
|
-
}
|
|
12152
|
-
function buildSlideContent(explainer, opts = {}) {
|
|
12153
|
-
const width = slideCardWidth();
|
|
12154
|
-
const inner = width - 4;
|
|
12155
|
-
const lines = [];
|
|
12156
|
-
const title = opts.titleOverride ?? (explainer ? explainer.label : "Metrics");
|
|
12157
|
-
if (explainer) {
|
|
12158
|
-
const headerBits = [
|
|
12159
|
-
kindBadge(explainer),
|
|
12160
|
-
chalk9.dim(explainer.group)
|
|
12161
|
-
];
|
|
12162
|
-
if (opts.index != null && opts.total != null) {
|
|
12163
|
-
headerBits.push(chalk9.dim(`slide ${opts.index}/${opts.total}`));
|
|
12164
|
-
}
|
|
12165
|
-
lines.push(headerBits.join(chalk9.dim(" \xB7 ")));
|
|
12166
|
-
lines.push(chalk9.dim(explainer.tagline));
|
|
12167
|
-
lines.push("");
|
|
12168
|
-
if (opts.live) {
|
|
12169
|
-
const live = opts.live;
|
|
12170
|
-
const tone = statusToTone(live.status);
|
|
12171
|
-
const liveLine = `${statusDot(live.status)} ${bold("Your reading:")} ${bold(live.formatted)} ` + badge(String(live.status), tone);
|
|
12172
|
-
lines.push(truncateVisible(liveLine, inner));
|
|
12173
|
-
if (live.dollarLine) {
|
|
12174
|
-
lines.push(chalk9.dim(` $ ${live.dollarLine}`));
|
|
12175
|
-
}
|
|
12176
|
-
if (live.benchmarkNote) {
|
|
12177
|
-
lines.push(chalk9.dim(` ${live.benchmarkNote}`));
|
|
12178
|
-
}
|
|
12179
|
-
lines.push("");
|
|
12180
|
-
} else {
|
|
12181
|
-
const hint = explainer.benchmarkHint?.(opts.motion);
|
|
12182
|
-
if (hint) {
|
|
12183
|
-
lines.push(chalk9.dim(`Benchmark \xB7 ${hint}`));
|
|
12184
|
-
lines.push("");
|
|
12185
|
-
}
|
|
12186
|
-
}
|
|
12187
|
-
const visual = opts.visualOverride ?? explainer.visual;
|
|
12188
|
-
const visLines = renderVisual(visual, inner);
|
|
12189
|
-
if (visLines.length) {
|
|
12190
|
-
lines.push(...visLines);
|
|
12191
|
-
lines.push("");
|
|
12192
|
-
}
|
|
12193
|
-
lines.push(sectionHeading("What it means"));
|
|
12194
|
-
pushWrapped(lines, explainer.meaning, inner, " ");
|
|
12195
|
-
lines.push("");
|
|
12196
|
-
if (!opts.skipFormula) {
|
|
12197
|
-
lines.push(sectionHeading("How it's calculated"));
|
|
12198
|
-
pushWrapped(lines, explainer.how_computed, inner, " ");
|
|
12199
|
-
for (const f of explainer.formula_lines) {
|
|
12200
|
-
lines.push(paint("accent", ` ${f}`));
|
|
12201
|
-
}
|
|
12202
|
-
lines.push("");
|
|
12203
|
-
}
|
|
12204
|
-
if (opts.deepdive) {
|
|
12205
|
-
lines.push(sectionHeading("Deep dive"));
|
|
12206
|
-
pushWrapped(lines, explainer.expert_read, inner, " ");
|
|
12207
|
-
lines.push("");
|
|
12208
|
-
for (const bullet of explainer.deepdive) {
|
|
12209
|
-
pushWrapped(lines, `\xB7 ${bullet}`, inner, " ");
|
|
12210
|
-
}
|
|
12211
|
-
if (explainer.play_id) {
|
|
12212
|
-
lines.push("");
|
|
12213
|
-
lines.push(
|
|
12214
|
-
chalk9.dim(" Play: ") + paint("accent", explainer.play_id)
|
|
12215
|
-
);
|
|
12216
|
-
}
|
|
12217
|
-
lines.push("");
|
|
12218
|
-
}
|
|
12219
|
-
} else if (opts.visualOverride) {
|
|
12220
|
-
const visLines = renderVisual(opts.visualOverride, inner);
|
|
12221
|
-
if (visLines.length) {
|
|
12222
|
-
lines.push(...visLines);
|
|
12223
|
-
lines.push("");
|
|
12224
|
-
}
|
|
12225
|
-
}
|
|
12226
|
-
if (opts.extraLines?.length) {
|
|
12227
|
-
for (const line of opts.extraLines) {
|
|
12228
|
-
if (line === "") lines.push("");
|
|
12229
|
-
else pushWrapped(lines, line, inner);
|
|
12230
|
-
}
|
|
12231
|
-
}
|
|
12232
|
-
return { title, lines, width, inner };
|
|
12233
|
-
}
|
|
12234
|
-
function renderMetricSlide(explainer, opts = {}) {
|
|
12235
|
-
const { title, lines, width, inner } = buildSlideContent(explainer, opts);
|
|
12236
|
-
const border = (s) => paint("border", s);
|
|
12237
|
-
const termW = termWidth();
|
|
12238
|
-
const outerPad = " ".repeat(Math.max(0, Math.floor((termW - width) / 2)));
|
|
12239
|
-
const out = [];
|
|
12240
|
-
out.push("");
|
|
12241
|
-
out.push(`${outerPad}${border(`\u256D${"\u2500".repeat(width - 2)}\u256E`)}`);
|
|
12242
|
-
out.push(
|
|
12243
|
-
`${outerPad}${border("\u2502 ")}${padRight(sectionHeading(title), inner)}${border(" \u2502")}`
|
|
12244
|
-
);
|
|
12245
|
-
out.push(`${outerPad}${border(`\u251C${"\u2500".repeat(width - 2)}\u2524`)}`);
|
|
12246
|
-
for (const row of lines) {
|
|
12247
|
-
out.push(
|
|
12248
|
-
`${outerPad}${border("\u2502 ")}${padRight(truncateVisible(row, inner), inner)}${border(" \u2502")}`
|
|
12249
|
-
);
|
|
12250
|
-
}
|
|
12251
|
-
const footer = opts.footer ?? (opts.deepdive ? `\u23CE next \xB7 b back \xB7 q quit` : `\u23CE next \xB7 /deepdive more \xB7 b back \xB7 q quit`);
|
|
12252
|
-
out.push(`${outerPad}${border(`\u251C${"\u2500".repeat(width - 2)}\u2524`)}`);
|
|
12253
|
-
out.push(
|
|
12254
|
-
`${outerPad}${border("\u2502 ")}${padRight(chalk9.dim(truncateVisible(footer, inner)), inner)}${border(" \u2502")}`
|
|
12255
|
-
);
|
|
12256
|
-
out.push(`${outerPad}${border(`\u2570${"\u2500".repeat(width - 2)}\u256F`)}`);
|
|
12257
|
-
out.push("");
|
|
12258
|
-
if (opts.asLines) return out;
|
|
12259
|
-
for (const line of out) console.log(line);
|
|
12260
|
-
}
|
|
12261
|
-
function progressDots(index, total) {
|
|
12262
|
-
const parts = [];
|
|
12263
|
-
for (let i = 1; i <= total; i++) {
|
|
12264
|
-
parts.push(i === index ? paint("accent", "\u25CF") : chalk9.dim("\u25CB"));
|
|
12265
|
-
}
|
|
12266
|
-
return parts.join("");
|
|
12267
|
-
}
|
|
12268
|
-
function printExplainerCatalogLine(explainer) {
|
|
12269
|
-
const kind = explainer.kind === "vital" ? paint("accent", "vital") : chalk9.dim("saas ");
|
|
12270
|
-
console.log(
|
|
12271
|
-
` ${kind} ${bold(explainer.id.padEnd(20))} ${chalk9.dim(explainer.label)} \u2014 ${chalk9.dim(explainer.tagline)}`
|
|
12272
|
-
);
|
|
12273
|
-
}
|
|
12274
|
-
function printGuideCatalogLine(slide) {
|
|
12275
|
-
console.log(
|
|
12276
|
-
` ${paint("accent", "how ")} ${bold(slide.id.padEnd(20))} ${chalk9.dim(slide.label)} \u2014 ${chalk9.dim(slide.tagline)}`
|
|
12277
|
-
);
|
|
12278
|
-
}
|
|
12279
|
-
function printDeepdiveHint(metricId, label) {
|
|
12280
|
-
const name = label ?? metricId;
|
|
12281
|
-
console.log(
|
|
12282
|
-
" " + chalk9.dim("How this number works: ") + paint("accent", `/deepdive ${metricId}`) + chalk9.dim(` \u2014 ${name}`)
|
|
12283
|
-
);
|
|
12284
|
-
console.log();
|
|
12285
|
-
}
|
|
12286
|
-
var init_slides = __esm({
|
|
12287
|
-
"src/ui/slides.ts"() {
|
|
12288
|
-
"use strict";
|
|
12289
|
-
init_theme();
|
|
12290
|
-
init_layout();
|
|
12291
|
-
}
|
|
12292
|
-
});
|
|
12293
|
-
|
|
12294
12330
|
// src/conversation/metric-tour.ts
|
|
12295
12331
|
var metric_tour_exports = {};
|
|
12296
12332
|
__export(metric_tour_exports, {
|
|
12297
12333
|
METRICS_TOUR_MILESTONE_ID: () => METRICS_TOUR_MILESTONE_ID,
|
|
12298
12334
|
describeTourDeck: () => describeTourDeck,
|
|
12335
|
+
firstRunTourDefaultChoice: () => firstRunTourDefaultChoice,
|
|
12299
12336
|
getDeepdiveNudge: () => getDeepdiveNudge,
|
|
12300
12337
|
hasAnalysisForDeepdiveNudge: () => hasAnalysisForDeepdiveNudge,
|
|
12301
12338
|
hasCompletedMetricsTour: () => hasCompletedMetricsTour,
|
|
@@ -12343,6 +12380,7 @@ function hasAnalysisForDeepdiveNudge(ctx) {
|
|
|
12343
12380
|
}
|
|
12344
12381
|
}
|
|
12345
12382
|
function getDeepdiveNudge(ctx) {
|
|
12383
|
+
if (!hasValidLicense()) return null;
|
|
12346
12384
|
if (hasCompletedMetricsTour() || hasSeenDeepdiveHomeNudge()) return null;
|
|
12347
12385
|
if (!hasAnalysisForDeepdiveNudge(ctx)) return null;
|
|
12348
12386
|
return {
|
|
@@ -12622,6 +12660,9 @@ function printGuideCard(slideId, opts = {}) {
|
|
|
12622
12660
|
});
|
|
12623
12661
|
return true;
|
|
12624
12662
|
}
|
|
12663
|
+
function firstRunTourDefaultChoice() {
|
|
12664
|
+
return loadProgress().milestones_unlocked.includes(METRICS_TOUR_MILESTONE_ID) ? "skip" : "tour";
|
|
12665
|
+
}
|
|
12625
12666
|
async function offerFirstRunTour(ctx) {
|
|
12626
12667
|
if (hasCompletedMetricsTour()) return false;
|
|
12627
12668
|
console.log();
|
|
@@ -12629,6 +12670,10 @@ async function offerFirstRunTour(ctx) {
|
|
|
12629
12670
|
console.log(
|
|
12630
12671
|
" " + chalk10.dim("SaaS numbers, five vitals, then how to talk to NTRP and ship work to Claude.")
|
|
12631
12672
|
);
|
|
12673
|
+
const tourDefault = firstRunTourDefaultChoice();
|
|
12674
|
+
if (tourDefault === "skip") {
|
|
12675
|
+
console.log(" " + chalk10.dim("You have taken this tour before."));
|
|
12676
|
+
}
|
|
12632
12677
|
console.log();
|
|
12633
12678
|
const session = createPromptSession(ctx.rl, ctx);
|
|
12634
12679
|
try {
|
|
@@ -12646,7 +12691,7 @@ async function offerFirstRunTour(ctx) {
|
|
|
12646
12691
|
description: "Re-open anytime with /deepdive or /deepdive guide"
|
|
12647
12692
|
}
|
|
12648
12693
|
],
|
|
12649
|
-
{ default:
|
|
12694
|
+
{ default: tourDefault }
|
|
12650
12695
|
);
|
|
12651
12696
|
if (choice === "skip") {
|
|
12652
12697
|
markMetricsTourSkipped();
|
|
@@ -12671,6 +12716,7 @@ var init_metric_tour = __esm({
|
|
|
12671
12716
|
init_prompts();
|
|
12672
12717
|
init_store();
|
|
12673
12718
|
init_progress();
|
|
12719
|
+
init_activation();
|
|
12674
12720
|
init_profile();
|
|
12675
12721
|
init_metric_definitions();
|
|
12676
12722
|
init_guide_slides();
|
|
@@ -15284,7 +15330,7 @@ var init_explore_mode = __esm({
|
|
|
15284
15330
|
|
|
15285
15331
|
// src/conversation/recommended-action.ts
|
|
15286
15332
|
function resolveRecommendedAction(ctx) {
|
|
15287
|
-
if (!hasValidLicense()) return { submit: "/
|
|
15333
|
+
if (!hasValidLicense()) return { submit: "/activate", hint: "/activate" };
|
|
15288
15334
|
const phase = resolveConversationPhase(ctx);
|
|
15289
15335
|
switch (phase) {
|
|
15290
15336
|
case "explore":
|
|
@@ -15298,6 +15344,8 @@ function resolveRecommendedAction(ctx) {
|
|
|
15298
15344
|
return { submit: "yes", hint: "yes" };
|
|
15299
15345
|
case "strategize":
|
|
15300
15346
|
return ctx.strategistState?.step === "objective_confirm" ? { submit: "yes", hint: "yes" } : null;
|
|
15347
|
+
case "think":
|
|
15348
|
+
return null;
|
|
15301
15349
|
default:
|
|
15302
15350
|
return null;
|
|
15303
15351
|
}
|
|
@@ -15332,6 +15380,9 @@ function resolveConversationPhase(ctx) {
|
|
|
15332
15380
|
if (ctx.strategistState && ctx.strategistState.step !== "awaiting_analysis" && ctx.strategistState.step !== "awaiting_connect") {
|
|
15333
15381
|
return "strategize";
|
|
15334
15382
|
}
|
|
15383
|
+
if (ctx.thinkState?.step === "active") {
|
|
15384
|
+
return "think";
|
|
15385
|
+
}
|
|
15335
15386
|
if (isAnalysisReady(ctx)) return "explore";
|
|
15336
15387
|
const scope = ctx.scope;
|
|
15337
15388
|
if (scope?.confirmed_at) {
|
|
@@ -15345,6 +15396,9 @@ function consumeOrientEmptyEnterCoach(ctx) {
|
|
|
15345
15396
|
if (resolveConversationPhase(ctx) !== "orient") return null;
|
|
15346
15397
|
if (ctx.orientEmptyEnterSeen) return null;
|
|
15347
15398
|
ctx.orientEmptyEnterSeen = true;
|
|
15399
|
+
if (!hasValidLicense()) {
|
|
15400
|
+
return "Type /activate to paste a key. Type /checkout if you need to sign up.";
|
|
15401
|
+
}
|
|
15348
15402
|
return "Type a question, type use demo data, or type /deepdive. Enter alone does not start a step here.";
|
|
15349
15403
|
}
|
|
15350
15404
|
function formatPhaseLabel(phase) {
|
|
@@ -15353,6 +15407,8 @@ function formatPhaseLabel(phase) {
|
|
|
15353
15407
|
return "setup";
|
|
15354
15408
|
case "explore":
|
|
15355
15409
|
return "ready to ask";
|
|
15410
|
+
case "think":
|
|
15411
|
+
return "thinking together";
|
|
15356
15412
|
default:
|
|
15357
15413
|
return phase.replace(/_/g, " ");
|
|
15358
15414
|
}
|
|
@@ -15371,8 +15427,14 @@ function buildConversationPrompt(ctx) {
|
|
|
15371
15427
|
const modeTag = mode === "brief" ? "brief" : "deep";
|
|
15372
15428
|
const stack = canUseReplAi(ctx) ? formatActiveStackShort(ctx) : "no engine";
|
|
15373
15429
|
const strategyWait = ctx.strategistState?.step === "awaiting_connect" ? chalk11.dim(" \xB7 strategy after /connect") : "";
|
|
15430
|
+
const thinkWait = ctx.thinkState?.step === "awaiting_connect" ? chalk11.dim(" \xB7 think after /connect") : "";
|
|
15431
|
+
const enterHint2 = action ? chalk11.dim(` \xB7 \u23CE ${action.hint}`) : "";
|
|
15432
|
+
return paint("accent", `ask${scope} \u203A `) + chalk11.dim(`${modeTag} \xB7 ${stack}`) + strategyWait + thinkWait + enterHint2 + " ";
|
|
15433
|
+
}
|
|
15434
|
+
if (phase === "think") {
|
|
15435
|
+
const stack = canUseReplAi(ctx) ? formatActiveStackShort(ctx) : "no engine";
|
|
15374
15436
|
const enterHint2 = action ? chalk11.dim(` \xB7 \u23CE ${action.hint}`) : "";
|
|
15375
|
-
return paint("accent", `
|
|
15437
|
+
return paint("accent", `think${scope} \u203A `) + chalk11.dim(stack) + enterHint2 + " ";
|
|
15376
15438
|
}
|
|
15377
15439
|
const enterHint = action ? chalk11.dim(`\u23CE ${action.hint} `) : "";
|
|
15378
15440
|
return paint("accent", `${label.replace(" \u203A", "")}${scope} \u203A `) + enterHint;
|
|
@@ -15405,6 +15467,7 @@ var init_phase = __esm({
|
|
|
15405
15467
|
init_explore_mode();
|
|
15406
15468
|
init_session_state();
|
|
15407
15469
|
init_theme();
|
|
15470
|
+
init_activation();
|
|
15408
15471
|
init_recommended_action();
|
|
15409
15472
|
PROMPT_LABELS = {
|
|
15410
15473
|
orient: "\u203A",
|
|
@@ -15412,6 +15475,7 @@ var init_phase = __esm({
|
|
|
15412
15475
|
awaiting_data: "data \u203A",
|
|
15413
15476
|
compute: "\u2026",
|
|
15414
15477
|
explore: "ask \u203A",
|
|
15478
|
+
think: "think \u203A",
|
|
15415
15479
|
strategize: "strategy \u203A",
|
|
15416
15480
|
deliver: "ship \u203A"
|
|
15417
15481
|
};
|
|
@@ -19738,9 +19802,11 @@ var inbox_setup_exports = {};
|
|
|
19738
19802
|
__export(inbox_setup_exports, {
|
|
19739
19803
|
maybeOfferInboxOnProduction: () => maybeOfferInboxOnProduction,
|
|
19740
19804
|
offerInboxSkillSetup: () => offerInboxSkillSetup,
|
|
19805
|
+
reuseInboxFolderIfPresent: () => reuseInboxFolderIfPresent,
|
|
19741
19806
|
shouldOfferInboxSkillSetup: () => shouldOfferInboxSkillSetup
|
|
19742
19807
|
});
|
|
19743
19808
|
import chalk19 from "chalk";
|
|
19809
|
+
import { existsSync as existsSync22 } from "fs";
|
|
19744
19810
|
function markDemoOffered() {
|
|
19745
19811
|
setConfigValue("ai-inbox-nudge-seen", "true");
|
|
19746
19812
|
}
|
|
@@ -19769,6 +19835,23 @@ function printSkipHint(beat) {
|
|
|
19769
19835
|
" " + chalk19.dim("Skipped. NTRP will not ask again. Type ") + setCmd + chalk19.dim(" then ") + skillCmd + chalk19.dim(" at any time.")
|
|
19770
19836
|
);
|
|
19771
19837
|
}
|
|
19838
|
+
async function reuseInboxFolderIfPresent(session, beat, folderPath = defaultAiInboxDir()) {
|
|
19839
|
+
if (getAiInboxDir()) return false;
|
|
19840
|
+
if (!existsSync22(folderPath)) return false;
|
|
19841
|
+
console.log(" " + chalk19.dim("Pickup folder still on disk: ") + folderPath);
|
|
19842
|
+
const reuse = await session.confirm("Reuse this pickup folder?", true);
|
|
19843
|
+
if (!reuse) return false;
|
|
19844
|
+
const resolved = setAiInboxDir(folderPath);
|
|
19845
|
+
markDemoOffered();
|
|
19846
|
+
if (beat === "production") markProductionOffered();
|
|
19847
|
+
console.log();
|
|
19848
|
+
console.log(" " + paint("accent", "Inbox ready") + chalk19.dim(" ") + resolved);
|
|
19849
|
+
console.log(
|
|
19850
|
+
" " + chalk19.dim("Folder reused. Type ") + paint("accent", "/inbox skill") + chalk19.dim(" to print the finder again.")
|
|
19851
|
+
);
|
|
19852
|
+
console.log();
|
|
19853
|
+
return true;
|
|
19854
|
+
}
|
|
19772
19855
|
async function offerInboxSkillSetup(session, opts = {}) {
|
|
19773
19856
|
const beat = opts.beat ?? "production";
|
|
19774
19857
|
if (!shouldOfferInboxSkillSetup(beat)) return;
|
|
@@ -19783,6 +19866,7 @@ async function offerInboxSkillSetup(session, opts = {}) {
|
|
|
19783
19866
|
console.log(" " + chalk19.dim("You skipped this during demo."));
|
|
19784
19867
|
}
|
|
19785
19868
|
console.log();
|
|
19869
|
+
if (await reuseInboxFolderIfPresent(session, beat)) return;
|
|
19786
19870
|
const want = await session.confirm("Set a pickup folder for Claude, ChatGPT, or Cursor?", true);
|
|
19787
19871
|
if (!want) {
|
|
19788
19872
|
if (beat === "demo") markDemoOffered();
|
|
@@ -19853,7 +19937,7 @@ __export(ingest_exports, {
|
|
|
19853
19937
|
handler: () => handler2
|
|
19854
19938
|
});
|
|
19855
19939
|
import chalk20 from "chalk";
|
|
19856
|
-
import { readFileSync as readFileSync19, existsSync as
|
|
19940
|
+
import { readFileSync as readFileSync19, existsSync as existsSync23 } from "fs";
|
|
19857
19941
|
import { basename as basename6 } from "path";
|
|
19858
19942
|
async function handler2(args, ctx) {
|
|
19859
19943
|
const { positional, flags } = parseArgs2(args, [
|
|
@@ -19877,7 +19961,7 @@ async function handler2(args, ctx) {
|
|
|
19877
19961
|
console.error(chalk20.dim(" /ingest --demo [--scenario <name>]"));
|
|
19878
19962
|
process.exit(1);
|
|
19879
19963
|
}
|
|
19880
|
-
if (!
|
|
19964
|
+
if (!existsSync23(file)) {
|
|
19881
19965
|
console.error(chalk20.red(` File not found: ${file}`));
|
|
19882
19966
|
process.exit(1);
|
|
19883
19967
|
}
|
|
@@ -20505,13 +20589,21 @@ function buildFreshNlTools() {
|
|
|
20505
20589
|
if (isWebRetrievalEnabled()) tools.push(WEB_SEARCH_TOOL);
|
|
20506
20590
|
return tools;
|
|
20507
20591
|
}
|
|
20592
|
+
function buildThinkTools() {
|
|
20593
|
+
const tools = [
|
|
20594
|
+
...AGENTIC_TOOLS,
|
|
20595
|
+
...THINK_CHANNEL_TOOLS
|
|
20596
|
+
];
|
|
20597
|
+
if (isWebRetrievalEnabled()) tools.push(WEB_SEARCH_TOOL);
|
|
20598
|
+
return tools;
|
|
20599
|
+
}
|
|
20508
20600
|
function allRegisteredToolSchemas() {
|
|
20509
|
-
return [...AGENTIC_TOOLS, ...CONVERSATION_TOOLS, WEB_SEARCH_TOOL];
|
|
20601
|
+
return [...AGENTIC_TOOLS, ...CONVERSATION_TOOLS, ...THINK_CHANNEL_TOOLS, WEB_SEARCH_TOOL];
|
|
20510
20602
|
}
|
|
20511
20603
|
function getToolSchema(name) {
|
|
20512
20604
|
return allRegisteredToolSchemas().find((t) => t.name === name);
|
|
20513
20605
|
}
|
|
20514
|
-
var WEB_SEARCH_TOOL, CONVERSATION_TOOLS, AGENTIC_TOOLS;
|
|
20606
|
+
var WEB_SEARCH_TOOL, CONVERSATION_TOOLS, THINK_CHANNEL_TOOLS, AGENTIC_TOOLS;
|
|
20515
20607
|
var init_tool_schemas = __esm({
|
|
20516
20608
|
"src/ai/tool-schemas.ts"() {
|
|
20517
20609
|
"use strict";
|
|
@@ -20588,6 +20680,64 @@ var init_tool_schemas = __esm({
|
|
|
20588
20680
|
}
|
|
20589
20681
|
}
|
|
20590
20682
|
];
|
|
20683
|
+
THINK_CHANNEL_TOOLS = [
|
|
20684
|
+
{
|
|
20685
|
+
name: "draft_handoff",
|
|
20686
|
+
description: "Draft a handoff prompt combining analysis numbers and conversation thread.",
|
|
20687
|
+
parameters: {
|
|
20688
|
+
type: "object",
|
|
20689
|
+
properties: {
|
|
20690
|
+
target: {
|
|
20691
|
+
type: "string",
|
|
20692
|
+
enum: ["deck", "asana", "clay", "plan"],
|
|
20693
|
+
description: "Deliverable type. Defaults to plan."
|
|
20694
|
+
}
|
|
20695
|
+
}
|
|
20696
|
+
}
|
|
20697
|
+
},
|
|
20698
|
+
{
|
|
20699
|
+
name: "draft_strategy",
|
|
20700
|
+
description: "Hand off to the strategist brain from the think channel when the user is ready to commit to a plan. Do not improvise a multi-week roadmap inline \u2014 call this instead.",
|
|
20701
|
+
parameters: {
|
|
20702
|
+
type: "object",
|
|
20703
|
+
properties: {
|
|
20704
|
+
objective: {
|
|
20705
|
+
type: "string",
|
|
20706
|
+
maxLength: 2e3,
|
|
20707
|
+
description: "The measurable objective to plan toward, in the user's terms."
|
|
20708
|
+
}
|
|
20709
|
+
},
|
|
20710
|
+
required: ["objective"]
|
|
20711
|
+
}
|
|
20712
|
+
},
|
|
20713
|
+
{
|
|
20714
|
+
name: "update_think_scratch",
|
|
20715
|
+
description: "Update the think-channel working scratch: open questions, challenged assumptions, and working hypotheses. Pass only the arrays you want to replace; omitted fields stay unchanged. Call when the conversation advances a question, surfaces a challenged assumption, or forms a hypothesis.",
|
|
20716
|
+
parameters: {
|
|
20717
|
+
type: "object",
|
|
20718
|
+
properties: {
|
|
20719
|
+
open_questions: {
|
|
20720
|
+
type: "array",
|
|
20721
|
+
items: { type: "string", maxLength: 500 },
|
|
20722
|
+
maxItems: 12,
|
|
20723
|
+
description: "Current open questions (replaces the list when provided)."
|
|
20724
|
+
},
|
|
20725
|
+
challenged_assumptions: {
|
|
20726
|
+
type: "array",
|
|
20727
|
+
items: { type: "string", maxLength: 500 },
|
|
20728
|
+
maxItems: 12,
|
|
20729
|
+
description: "Assumptions that have been pressure-tested (replaces when provided)."
|
|
20730
|
+
},
|
|
20731
|
+
working_hypotheses: {
|
|
20732
|
+
type: "array",
|
|
20733
|
+
items: { type: "string", maxLength: 500 },
|
|
20734
|
+
maxItems: 12,
|
|
20735
|
+
description: "Working hypotheses under consideration (replaces when provided)."
|
|
20736
|
+
}
|
|
20737
|
+
}
|
|
20738
|
+
}
|
|
20739
|
+
}
|
|
20740
|
+
];
|
|
20591
20741
|
AGENTIC_TOOLS = [
|
|
20592
20742
|
{
|
|
20593
20743
|
name: "get_health_summary",
|
|
@@ -21754,6 +21904,7 @@ async function handleDraftStrategy(input) {
|
|
|
21754
21904
|
if (!objective) return { error: "objective is required." };
|
|
21755
21905
|
if (!isAnalysisReady2(ctx)) {
|
|
21756
21906
|
ctx.strategistState = { step: "awaiting_analysis", objective, origin: "ai" };
|
|
21907
|
+
if (ctx.thinkState) ctx.thinkState = void 0;
|
|
21757
21908
|
saveSessionState2(ctx);
|
|
21758
21909
|
return {
|
|
21759
21910
|
queued: true,
|
|
@@ -21762,6 +21913,7 @@ async function handleDraftStrategy(input) {
|
|
|
21762
21913
|
};
|
|
21763
21914
|
}
|
|
21764
21915
|
ctx.strategistState = { step: "objective_confirm", objective, origin: "ai" };
|
|
21916
|
+
if (ctx.thinkState) ctx.thinkState = void 0;
|
|
21765
21917
|
saveSessionState2(ctx);
|
|
21766
21918
|
return {
|
|
21767
21919
|
launched: true,
|
|
@@ -21769,6 +21921,32 @@ async function handleDraftStrategy(input) {
|
|
|
21769
21921
|
note: "Strategist handoff armed. After your reply the user sees an objective confirmation card and the engine runs a full grounding/backcast/stress-test session. Keep your reply to one or two sentences introducing the handoff \u2014 do NOT write the plan yourself."
|
|
21770
21922
|
};
|
|
21771
21923
|
}
|
|
21924
|
+
async function handleUpdateThinkScratch(input) {
|
|
21925
|
+
const { getAgentContext: getAgentContext2 } = await Promise.resolve().then(() => (init_agent_context(), agent_context_exports));
|
|
21926
|
+
const { saveSessionState: saveSessionState2 } = await Promise.resolve().then(() => (init_context2(), context_exports));
|
|
21927
|
+
const ctx = getAgentContext2();
|
|
21928
|
+
if (!ctx) return { error: "No active session context." };
|
|
21929
|
+
if (!ctx.thinkState || ctx.thinkState.step !== "active") {
|
|
21930
|
+
return { error: "Think channel is not active." };
|
|
21931
|
+
}
|
|
21932
|
+
const asStringList = (value) => {
|
|
21933
|
+
if (!Array.isArray(value)) return void 0;
|
|
21934
|
+
return value.filter((v) => typeof v === "string").map((s) => s.trim()).filter(Boolean).slice(0, 12);
|
|
21935
|
+
};
|
|
21936
|
+
const open = asStringList(input.open_questions);
|
|
21937
|
+
const challenged = asStringList(input.challenged_assumptions);
|
|
21938
|
+
const hypotheses = asStringList(input.working_hypotheses);
|
|
21939
|
+
if (open) ctx.thinkState.open_questions = open;
|
|
21940
|
+
if (challenged) ctx.thinkState.challenged_assumptions = challenged;
|
|
21941
|
+
if (hypotheses) ctx.thinkState.working_hypotheses = hypotheses;
|
|
21942
|
+
saveSessionState2(ctx);
|
|
21943
|
+
return {
|
|
21944
|
+
updated: true,
|
|
21945
|
+
open_questions: ctx.thinkState.open_questions ?? [],
|
|
21946
|
+
challenged_assumptions: ctx.thinkState.challenged_assumptions ?? [],
|
|
21947
|
+
working_hypotheses: ctx.thinkState.working_hypotheses ?? []
|
|
21948
|
+
};
|
|
21949
|
+
}
|
|
21772
21950
|
async function handleGetSessionBrief(input) {
|
|
21773
21951
|
const raw = typeof input.session_id === "string" ? input.session_id.trim() : "";
|
|
21774
21952
|
if (!raw) return { error: "session_id is required." };
|
|
@@ -21783,9 +21961,9 @@ async function handleGetSessionBrief(input) {
|
|
|
21783
21961
|
if (!target) {
|
|
21784
21962
|
return { error: `No session matching "${raw}".` };
|
|
21785
21963
|
}
|
|
21786
|
-
const { existsSync:
|
|
21964
|
+
const { existsSync: existsSync34, readFileSync: readFileSync24 } = await import("fs");
|
|
21787
21965
|
const briefPath = contextDocPathForSession2(target.id);
|
|
21788
|
-
if (!
|
|
21966
|
+
if (!existsSync34(briefPath)) {
|
|
21789
21967
|
return {
|
|
21790
21968
|
session_id: target.id,
|
|
21791
21969
|
error: "No context brief on disk for this session (created before brief storage existed).",
|
|
@@ -21818,8 +21996,8 @@ function boundResultJson(resultJson) {
|
|
|
21818
21996
|
}
|
|
21819
21997
|
async function executeToolCall(name, input, ctx, policy = {}) {
|
|
21820
21998
|
const start = Date.now();
|
|
21821
|
-
const
|
|
21822
|
-
if (!
|
|
21999
|
+
const handler50 = HANDLERS[name];
|
|
22000
|
+
if (!handler50) {
|
|
21823
22001
|
const stopNote = policy.guard?.recordUnknownTool(name) ?? null;
|
|
21824
22002
|
const resultJson2 = JSON.stringify(
|
|
21825
22003
|
stopNote ? { error: `Unknown tool '${name}'`, guidance: stopNote } : { error: `Unknown tool '${name}'` }
|
|
@@ -21850,7 +22028,7 @@ async function executeToolCall(name, input, ctx, policy = {}) {
|
|
|
21850
22028
|
auditDenied(name, input, resultJson2, start);
|
|
21851
22029
|
return resultJson2;
|
|
21852
22030
|
}
|
|
21853
|
-
const rawResult = await
|
|
22031
|
+
const rawResult = await handler50(input, ctx);
|
|
21854
22032
|
const safeResult = stripPII(rawResult);
|
|
21855
22033
|
const withGuidance = loopVerdict.verdict === "warn" && safeResult && typeof safeResult === "object" && !Array.isArray(safeResult) ? { ...safeResult, loop_warning: loopVerdict.note } : safeResult;
|
|
21856
22034
|
const resultJson = boundResultJson(JSON.stringify(withGuidance));
|
|
@@ -21894,7 +22072,8 @@ var init_tool_handlers = __esm({
|
|
|
21894
22072
|
audit_data_gaps: (_, __) => handleAuditDataGaps(),
|
|
21895
22073
|
run_compute: (_, __) => handleRunCompute(),
|
|
21896
22074
|
draft_handoff: (input, _) => handleDraftHandoff(input),
|
|
21897
|
-
draft_strategy: (input, _) => handleDraftStrategy(input)
|
|
22075
|
+
draft_strategy: (input, _) => handleDraftStrategy(input),
|
|
22076
|
+
update_think_scratch: (input, _) => handleUpdateThinkScratch(input)
|
|
21898
22077
|
};
|
|
21899
22078
|
}
|
|
21900
22079
|
});
|
|
@@ -22043,8 +22222,171 @@ var init_thread = __esm({
|
|
|
22043
22222
|
}
|
|
22044
22223
|
});
|
|
22045
22224
|
|
|
22046
|
-
// src/ai/
|
|
22225
|
+
// src/ai/think-prompt.ts
|
|
22047
22226
|
function companyContextSection2() {
|
|
22227
|
+
const block = buildCompanyProfileBlock();
|
|
22228
|
+
return block ? `COMPANY CONTEXT:
|
|
22229
|
+
${block}
|
|
22230
|
+
|
|
22231
|
+
` : "";
|
|
22232
|
+
}
|
|
22233
|
+
function operatorSection2() {
|
|
22234
|
+
const block = buildOperatorBlock();
|
|
22235
|
+
return block ? `${block}
|
|
22236
|
+
|
|
22237
|
+
` : "";
|
|
22238
|
+
}
|
|
22239
|
+
function buildScratchBlock(state2) {
|
|
22240
|
+
if (!state2) return "";
|
|
22241
|
+
const lines = [];
|
|
22242
|
+
if (state2.seed) lines.push(`Seed topic: ${state2.seed}`);
|
|
22243
|
+
if (state2.open_questions?.length) {
|
|
22244
|
+
lines.push("Open questions:");
|
|
22245
|
+
for (const q of state2.open_questions) lines.push(`- ${q}`);
|
|
22246
|
+
}
|
|
22247
|
+
if (state2.challenged_assumptions?.length) {
|
|
22248
|
+
lines.push("Challenged assumptions:");
|
|
22249
|
+
for (const a of state2.challenged_assumptions) lines.push(`- ${a}`);
|
|
22250
|
+
}
|
|
22251
|
+
if (state2.working_hypotheses?.length) {
|
|
22252
|
+
lines.push("Working hypotheses:");
|
|
22253
|
+
for (const h of state2.working_hypotheses) lines.push(`- ${h}`);
|
|
22254
|
+
}
|
|
22255
|
+
if (lines.length === 0) return "";
|
|
22256
|
+
return `
|
|
22257
|
+
THINK SCRATCH (session working memory \u2014 update via update_think_scratch):
|
|
22258
|
+
${lines.join("\n")}
|
|
22259
|
+
`;
|
|
22260
|
+
}
|
|
22261
|
+
function buildThinkWithMeSystemPrompt(opts = {}) {
|
|
22262
|
+
const sessionBlock = opts.sessionContext ? `
|
|
22263
|
+
PREVIOUS SESSION CONTEXT:
|
|
22264
|
+
The user resumed an earlier session. Here is what they were investigating before:
|
|
22265
|
+
${opts.sessionContext}
|
|
22266
|
+
Treat this as already-established background. Pick up where it left off \u2014 do not re-introduce it as if it were new.
|
|
22267
|
+
|
|
22268
|
+
` : "";
|
|
22269
|
+
const memorySection = opts.memoryBlock ? `
|
|
22270
|
+
WHAT YOU ALREADY KNOW ABOUT THIS BUSINESS (durable memory):
|
|
22271
|
+
${opts.memoryBlock}
|
|
22272
|
+
Reference this naturally. Do not re-derive things you already know; build on them.
|
|
22273
|
+
|
|
22274
|
+
` : "";
|
|
22275
|
+
const analysisSection = opts.analysisBlock ? `
|
|
22276
|
+
SESSION ANALYSIS CONTEXT:
|
|
22277
|
+
${opts.analysisBlock}
|
|
22278
|
+
Use get_revenue_metrics and get_revenue_metrics_timeseries when the user asks about SaaS metrics, retention, or period trends.
|
|
22279
|
+
|
|
22280
|
+
` : "";
|
|
22281
|
+
const artifactSection = opts.sessionArtifact ? `
|
|
22282
|
+
COMPLETED SESSION ANALYSIS:
|
|
22283
|
+
${opts.sessionArtifact}
|
|
22284
|
+
Cite numbers from here; call tools when you need a new cut or to pressure-test a claim.
|
|
22285
|
+
|
|
22286
|
+
` : "";
|
|
22287
|
+
const conversationSection = opts.conversationBlock ? `
|
|
22288
|
+
CONVERSATION STATE:
|
|
22289
|
+
${opts.conversationBlock}
|
|
22290
|
+
|
|
22291
|
+
` : "";
|
|
22292
|
+
const scratchSection = buildScratchBlock(opts.thinkState);
|
|
22293
|
+
const socraticCraft = `HOW YOU THINK WITH THE USER (socratic partner \u2014 not a search box, not a strategist):
|
|
22294
|
+
- You are a thinking partner. Prefer sharp questions that unlock the user's idea over dumping answers.
|
|
22295
|
+
- Protect imagination: give "what if" space before the smell-test \u2014 do not kill creativity in the first sentence.
|
|
22296
|
+
- Steelman the user's position before you attack it; then deliver one hard pushback grounded in evidence when possible.
|
|
22297
|
+
- Ground claims about THIS pipeline in tool results. Label speculation explicitly ("hypothesis:", "speculation:").
|
|
22298
|
+
- Each turn should ADVANCE the thread: a new question, a challenge, a synthesis, or a fork \u2014 never rehash.
|
|
22299
|
+
- If the question is ambiguous, ask at most ONE clarifying question. Otherwise choose a fork and state it.
|
|
22300
|
+
- Never invent a multi-week roadmap inline. When they want commitment, call draft_strategy with a crisp objective.
|
|
22301
|
+
- Keep open_questions, challenged_assumptions, and working_hypotheses current via update_think_scratch.
|
|
22302
|
+
- You have continuity via prior think-channel messages. Never repeat an angle already covered unless asked.`;
|
|
22303
|
+
const jobSection = `YOUR JOB (THINK CHANNEL \u2014 always deep):
|
|
22304
|
+
- Decide whether you need tools, a direct answer, or both. Do not re-call a tool whose result you already have.
|
|
22305
|
+
- Lead with the answer or the question that matters most, then structure.
|
|
22306
|
+
- When you use numbers, include dollar values where available and lead with financial impact.
|
|
22307
|
+
- Descriptive exploration stays in this channel; plan-of-attack questions hand off via draft_strategy.
|
|
22308
|
+
- After a successful draft_strategy tool result: reply with at most 1\u20132 sentences introducing the handoff. Do not write the plan.`;
|
|
22309
|
+
const formattingSection = `
|
|
22310
|
+
FORMATTING (your answer is rendered in a terminal via a small markdown renderer):
|
|
22311
|
+
- Use **bold** for every dollar figure, score, play name, and person name.
|
|
22312
|
+
- Use *italics* for conversational asides and your closing follow-up question.
|
|
22313
|
+
- Use ### for section headings \u2014 never # or ##. The renderer flattens depth.
|
|
22314
|
+
- For multi-point answers, prefer a one-line lead + bullet list over long paragraph blocks.
|
|
22315
|
+
- Keep paragraphs to 3-4 sentences.
|
|
22316
|
+
- Prefer short tables (\u22643 columns, \u22645 rows, cells \u226430 chars).
|
|
22317
|
+
- End with a dim horizontal rule (---) followed by one italicized follow-up question or fork.
|
|
22318
|
+
|
|
22319
|
+
${USER_VISIBLE_STE_BLOCK}
|
|
22320
|
+
`;
|
|
22321
|
+
const commandSection = `PRESET COMMANDS (slash commands the user can type \u2014 you may SUGGEST these; you cannot run them):
|
|
22322
|
+
${buildCommandCatalogBlock()}
|
|
22323
|
+
|
|
22324
|
+
COMMAND SUGGESTION RULES:
|
|
22325
|
+
- Suggest at most ONE command when it adds capability beyond your answer (e.g. \`/strategy\`, \`/handoff\`).
|
|
22326
|
+
- Never claim a command was run. Never invent flags.
|
|
22327
|
+
- Type \`done\` or \`cancel\` leaves the think channel back to ask \u203A.`;
|
|
22328
|
+
const stable = `You are a world-class GTM operating partner in a dedicated THINK WITH ME channel. The user wants collaborative exploration \u2014 imagination, pressure-testing, and evidence \u2014 not a slide deck and not a finished strategy plan.
|
|
22329
|
+
|
|
22330
|
+
${companyContextSection2()}${operatorSection2()}${socraticCraft}
|
|
22331
|
+
|
|
22332
|
+
ANALYST INSTINCT (judgment a CEO pays for \u2014 apply by default):
|
|
22333
|
+
${ANALYST_INSTINCT_BLOCK}
|
|
22334
|
+
|
|
22335
|
+
${jobSection}
|
|
22336
|
+
|
|
22337
|
+
EXECUTION BIAS (how you work):
|
|
22338
|
+
${EXECUTION_BIAS_BLOCK}
|
|
22339
|
+
|
|
22340
|
+
GTM ENGINEERING (how recommendations become systems):
|
|
22341
|
+
${GTM_ENGINEERING_BLOCK}
|
|
22342
|
+
|
|
22343
|
+
OUTPUT DOCTRINE (how answers are structured for recall):
|
|
22344
|
+
${PYRAMID_OUTPUT_BLOCK}
|
|
22345
|
+
|
|
22346
|
+
${USER_VISIBLE_STE_BLOCK}
|
|
22347
|
+
|
|
22348
|
+
CONTEXT:
|
|
22349
|
+
The user's health scores and top divergences were included as JSON at the start of this conversation. Use them, the think-channel history, and SESSION STATE as background and as hints for which tools to call.
|
|
22350
|
+
|
|
22351
|
+
VITAL SIGNS EXPLAINED (with dollar translations):
|
|
22352
|
+
${VITAL_SIGNS_BLOCK}
|
|
22353
|
+
|
|
22354
|
+
PLAYBOOK \u2014 name a play when it helps the user act (not a full program):
|
|
22355
|
+
${buildPlaybookBlock()}
|
|
22356
|
+
|
|
22357
|
+
${commandSection}
|
|
22358
|
+
${formattingSection}
|
|
22359
|
+
OUTPUT RULES:
|
|
22360
|
+
- Respond in plain text markdown (not JSON). You do NOT need to emit the findings schema.
|
|
22361
|
+
- Include specific numbers from tool results, never guess.
|
|
22362
|
+
- When you have enough information, answer or ask \u2014 don't call tools you don't need.
|
|
22363
|
+
|
|
22364
|
+
SAFETY & EVIDENCE (non-negotiable):
|
|
22365
|
+
${SAFETY_BLOCK}`;
|
|
22366
|
+
const dynamicSections = [
|
|
22367
|
+
sessionBlock,
|
|
22368
|
+
memorySection,
|
|
22369
|
+
analysisSection,
|
|
22370
|
+
artifactSection,
|
|
22371
|
+
conversationSection,
|
|
22372
|
+
scratchSection
|
|
22373
|
+
].map((s) => s.trim()).filter(Boolean);
|
|
22374
|
+
const dynamic = [
|
|
22375
|
+
"SESSION STATE (current \u2014 changes as the session progresses):",
|
|
22376
|
+
...dynamicSections,
|
|
22377
|
+
buildRuntimeBlock()
|
|
22378
|
+
].join("\n\n");
|
|
22379
|
+
return { stable, dynamic };
|
|
22380
|
+
}
|
|
22381
|
+
var init_think_prompt = __esm({
|
|
22382
|
+
"src/ai/think-prompt.ts"() {
|
|
22383
|
+
"use strict";
|
|
22384
|
+
init_prompt_parts();
|
|
22385
|
+
}
|
|
22386
|
+
});
|
|
22387
|
+
|
|
22388
|
+
// src/ai/agentic-loop.ts
|
|
22389
|
+
function companyContextSection3() {
|
|
22048
22390
|
const block = buildCompanyProfileBlock();
|
|
22049
22391
|
if (!block) return "";
|
|
22050
22392
|
return `COMPANY CONTEXT (use this to make every answer specific to the business \u2014 use industry-appropriate language, anchor dollar figures to their deal size):
|
|
@@ -22052,7 +22394,7 @@ ${block}
|
|
|
22052
22394
|
|
|
22053
22395
|
`;
|
|
22054
22396
|
}
|
|
22055
|
-
function
|
|
22397
|
+
function operatorSection3() {
|
|
22056
22398
|
const block = buildOperatorBlock();
|
|
22057
22399
|
if (!block) return "";
|
|
22058
22400
|
return `${block}
|
|
@@ -22062,7 +22404,7 @@ function operatorSection2() {
|
|
|
22062
22404
|
function buildSystemPrompt() {
|
|
22063
22405
|
const stable = `You are an expert GTM health investigator. You have tools to query a local database of CRM and pipeline data. Your job is to investigate the health scores you've been given and discover the specific root causes behind any problems.
|
|
22064
22406
|
|
|
22065
|
-
${
|
|
22407
|
+
${companyContextSection3()}${operatorSection3()}INVESTIGATION APPROACH:
|
|
22066
22408
|
1. Start by examining the health summary to understand the overall picture
|
|
22067
22409
|
2. Drill into the lowest-scoring vital signs using get_vital_sign_detail
|
|
22068
22410
|
3. Check divergences to find segments that are significantly worse than average
|
|
@@ -22251,7 +22593,7 @@ ${buildPlaybookBlock()}
|
|
|
22251
22593
|
${commandSection}`;
|
|
22252
22594
|
const stable = `You are a world-class GTM operating partner \u2014 the kind of analyst a CEO keeps on speed dial. You are exceptionally well-read, rigorous, and commercially sharp, and you have tools to query a local database of this company's CRM and pipeline data. The user is having an ongoing, free-form conversation with you about their go-to-market health and SaaS metrics.
|
|
22253
22595
|
|
|
22254
|
-
${
|
|
22596
|
+
${companyContextSection3()}${operatorSection3()}${conversationRules}
|
|
22255
22597
|
|
|
22256
22598
|
${analystSection}
|
|
22257
22599
|
|
|
@@ -22297,20 +22639,27 @@ async function* agenticFindings(computeResult, divergences, options) {
|
|
|
22297
22639
|
assertReplAi(options.ctx);
|
|
22298
22640
|
const mode = options.mode ?? "investigation";
|
|
22299
22641
|
const experiment = options.experiment ?? "production";
|
|
22300
|
-
const responseMode = experiment === "baseline" || experiment === "a" || experiment === "b" ? "deep" : options.responseMode ?? (options.sessionArtifact ? "brief" : "deep");
|
|
22301
|
-
const useTools = mode === "investigation" || responseMode === "deep";
|
|
22642
|
+
const responseMode = mode === "think" ? "deep" : experiment === "baseline" || experiment === "a" || experiment === "b" ? "deep" : options.responseMode ?? (options.sessionArtifact ? "brief" : "deep");
|
|
22643
|
+
const useTools = mode === "investigation" || mode === "think" || responseMode === "deep";
|
|
22302
22644
|
const maxTokens = mode === "fresh" && responseMode === "brief" ? BRIEF_MAX_TOKENS : DEEP_MAX_TOKENS;
|
|
22303
22645
|
const surface = mode === "fresh" ? responseMode === "brief" ? "agentic_fresh_brief" : "agentic_investigation" : "agentic_investigation";
|
|
22304
22646
|
const llmCfg = loadLlmConfig();
|
|
22305
22647
|
const tier = tierForSurface(surface, llmCfg.tier);
|
|
22306
|
-
const systemPrompt = mode === "
|
|
22648
|
+
const systemPrompt = mode === "think" ? buildThinkWithMeSystemPrompt({
|
|
22649
|
+
sessionContext: options.sessionContext,
|
|
22650
|
+
memoryBlock: options.memoryBlock,
|
|
22651
|
+
analysisBlock: options.analysisBlock,
|
|
22652
|
+
conversationBlock: options.conversationBlock,
|
|
22653
|
+
sessionArtifact: options.sessionArtifact,
|
|
22654
|
+
thinkState: options.ctx.thinkState
|
|
22655
|
+
}) : mode === "fresh" ? buildFreshNlSystemPrompt(
|
|
22307
22656
|
options.sessionContext,
|
|
22308
22657
|
options.memoryBlock,
|
|
22309
22658
|
options.analysisBlock,
|
|
22310
22659
|
options.conversationBlock,
|
|
22311
22660
|
{ responseMode, sessionArtifact: options.sessionArtifact, experiment }
|
|
22312
22661
|
) : buildSystemPrompt();
|
|
22313
|
-
const tools = useTools ? mode === "fresh" ? buildFreshNlTools() : buildInvestigationTools() : [];
|
|
22662
|
+
const tools = useTools ? mode === "think" ? buildThinkTools() : mode === "fresh" ? buildFreshNlTools() : buildInvestigationTools() : [];
|
|
22314
22663
|
const toolCtx = { computeResult, divergences };
|
|
22315
22664
|
if (options.includeMetrics) {
|
|
22316
22665
|
try {
|
|
@@ -22322,7 +22671,8 @@ async function* agenticFindings(computeResult, divergences, options) {
|
|
|
22322
22671
|
const initialContext = buildInitialContext(computeResult, divergences, options.userQuestion);
|
|
22323
22672
|
const priorRaw = options.priorMessages ?? [];
|
|
22324
22673
|
const priorMessages = priorRaw.length > 0 && typeof priorRaw[0] === "object" && priorRaw[0] !== null && "content" in priorRaw[0] ? normalizeThread(priorRaw) : priorRaw;
|
|
22325
|
-
const
|
|
22674
|
+
const conversational = mode === "fresh" || mode === "think";
|
|
22675
|
+
const messages = conversational && priorMessages.length > 0 && options.userQuestion ? [...priorMessages, { role: "user", content: options.userQuestion }] : [{ role: "user", content: initialContext }];
|
|
22326
22676
|
let lastMeta = { provider_used: "anthropic", model_used: "unknown" };
|
|
22327
22677
|
const loopGuard = new ToolLoopGuard();
|
|
22328
22678
|
const allowedTools = new Set(tools.map((t) => t.name));
|
|
@@ -22352,7 +22702,7 @@ async function* agenticFindings(computeResult, divergences, options) {
|
|
|
22352
22702
|
const response = await callLlm(messages, maxTokens, true);
|
|
22353
22703
|
if (response.tool_calls.length === 0) {
|
|
22354
22704
|
const fullText = response.text;
|
|
22355
|
-
if (
|
|
22705
|
+
if (conversational) {
|
|
22356
22706
|
const findings3 = parseFindings(fullText);
|
|
22357
22707
|
if (findings3.length > 0) {
|
|
22358
22708
|
for (const finding of findings3) yield { type: "finding", finding };
|
|
@@ -22400,7 +22750,7 @@ async function* agenticFindings(computeResult, divergences, options) {
|
|
|
22400
22750
|
});
|
|
22401
22751
|
}
|
|
22402
22752
|
}
|
|
22403
|
-
if (
|
|
22753
|
+
if (conversational) {
|
|
22404
22754
|
messages.push({
|
|
22405
22755
|
role: "user",
|
|
22406
22756
|
content: "You've reached the tool budget. Please answer the user's question now with what you've learned."
|
|
@@ -22476,6 +22826,7 @@ var init_agentic_loop = __esm({
|
|
|
22476
22826
|
init_thread();
|
|
22477
22827
|
init_untrusted();
|
|
22478
22828
|
init_prompt_parts();
|
|
22829
|
+
init_think_prompt();
|
|
22479
22830
|
MAX_ITERATIONS = 10;
|
|
22480
22831
|
INVESTIGATION_EVIDENCE_NUDGE_AFTER = 5;
|
|
22481
22832
|
BRIEF_MAX_TOKENS = 768;
|
|
@@ -24192,7 +24543,7 @@ __export(new_exports, {
|
|
|
24192
24543
|
handler: () => handler6
|
|
24193
24544
|
});
|
|
24194
24545
|
import chalk25 from "chalk";
|
|
24195
|
-
import { existsSync as
|
|
24546
|
+
import { existsSync as existsSync24 } from "fs";
|
|
24196
24547
|
import { basename as basename7 } from "path";
|
|
24197
24548
|
async function handler6(args, ctx) {
|
|
24198
24549
|
const { positional, flags } = parseArgs2(args, ["demo", "empty", "list-scenarios", "regen-taxonomy"]);
|
|
@@ -24214,7 +24565,7 @@ async function handler6(args, ctx) {
|
|
|
24214
24565
|
console.error(chalk25.red(" Usage: /new <file.csv> | --demo [--scenario <name>] | --empty [--lens health|metrics]"));
|
|
24215
24566
|
return;
|
|
24216
24567
|
}
|
|
24217
|
-
if (source.kind === "file" && !
|
|
24568
|
+
if (source.kind === "file" && !existsSync24(source.path)) {
|
|
24218
24569
|
console.error(chalk25.red(` File not found: ${source.path}`));
|
|
24219
24570
|
return;
|
|
24220
24571
|
}
|
|
@@ -24441,7 +24792,7 @@ __export(end_exports, {
|
|
|
24441
24792
|
handler: () => handler7
|
|
24442
24793
|
});
|
|
24443
24794
|
import chalk26 from "chalk";
|
|
24444
|
-
import { existsSync as
|
|
24795
|
+
import { existsSync as existsSync25 } from "fs";
|
|
24445
24796
|
async function handler7(args, ctx) {
|
|
24446
24797
|
if (args.length > 0) {
|
|
24447
24798
|
console.error(chalk26.red(" Usage: /end"));
|
|
@@ -24478,10 +24829,10 @@ async function handler7(args, ctx) {
|
|
|
24478
24829
|
if (summary) {
|
|
24479
24830
|
console.log(" " + chalk26.dim(summary));
|
|
24480
24831
|
}
|
|
24481
|
-
if (
|
|
24832
|
+
if (existsSync25(transcriptPathForSession(endedId))) {
|
|
24482
24833
|
console.log(" " + chalk26.dim("Transcript: ") + chalk26.dim(transcriptPathForSession(endedId)));
|
|
24483
24834
|
}
|
|
24484
|
-
if (
|
|
24835
|
+
if (existsSync25(contextDocPathForSession(endedId))) {
|
|
24485
24836
|
console.log(" " + chalk26.dim("Context brief: ") + chalk26.dim(contextDocPathForSession(endedId)));
|
|
24486
24837
|
}
|
|
24487
24838
|
console.log();
|
|
@@ -24503,7 +24854,7 @@ __export(session_exports, {
|
|
|
24503
24854
|
});
|
|
24504
24855
|
import chalk27 from "chalk";
|
|
24505
24856
|
import { join as join23 } from "path";
|
|
24506
|
-
import { existsSync as
|
|
24857
|
+
import { existsSync as existsSync26 } from "fs";
|
|
24507
24858
|
async function handler8(args, ctx) {
|
|
24508
24859
|
const sub = args[0];
|
|
24509
24860
|
if (!sub) return listSessionsView(ctx);
|
|
@@ -24610,6 +24961,7 @@ async function pickUp(idArg, ctx) {
|
|
|
24610
24961
|
sessionName: session.name,
|
|
24611
24962
|
messages: [...session.messages],
|
|
24612
24963
|
conversation: session.thread ? [...session.thread] : [],
|
|
24964
|
+
thinkConversation: session.think_thread ? [...session.think_thread] : [],
|
|
24613
24965
|
resumedSessionSummary: session.summary,
|
|
24614
24966
|
stage: session.stage ?? (session.messages.length > 0 ? "analyzed" : "new"),
|
|
24615
24967
|
dataset: session.dataset,
|
|
@@ -24619,6 +24971,7 @@ async function pickUp(idArg, ctx) {
|
|
|
24619
24971
|
attachments: session.attachments,
|
|
24620
24972
|
llm: session.llm ? { ...session.llm } : void 0,
|
|
24621
24973
|
strategistState: session.strategist,
|
|
24974
|
+
thinkState: session.think,
|
|
24622
24975
|
pendingAsk: session.pending_ask
|
|
24623
24976
|
});
|
|
24624
24977
|
ctx.datasetPath = datasetPathForSession(target.id);
|
|
@@ -24640,8 +24993,14 @@ async function pickUp(idArg, ctx) {
|
|
|
24640
24993
|
" " + chalk27.yellow("Resuming mid-strategy") + (objective ? chalk27.dim(`: "${objective}"`) : "") + chalk27.dim(" \u2014 say ") + chalk27.cyan("yes") + chalk27.dim(" to continue or ") + chalk27.cyan("cancel") + chalk27.dim(" to drop it.")
|
|
24641
24994
|
);
|
|
24642
24995
|
}
|
|
24996
|
+
if (session.think && session.think.step === "active") {
|
|
24997
|
+
const seed = session.think.seed;
|
|
24998
|
+
console.log(
|
|
24999
|
+
" " + chalk27.yellow("Resuming think channel") + (seed ? chalk27.dim(`: "${seed}"`) : "") + chalk27.dim(" \u2014 keep exploring or type ") + chalk27.cyan("done") + chalk27.dim(" / ") + chalk27.cyan("cancel") + chalk27.dim(" to leave.")
|
|
25000
|
+
);
|
|
25001
|
+
}
|
|
24643
25002
|
const contextPath = contextDocPathForSession(target.id);
|
|
24644
|
-
if (
|
|
25003
|
+
if (existsSync26(contextPath)) {
|
|
24645
25004
|
console.log(" " + chalk27.dim("Context brief: ") + chalk27.dim(contextPath));
|
|
24646
25005
|
}
|
|
24647
25006
|
console.log();
|
|
@@ -27144,7 +27503,7 @@ var init_strategist = __esm({
|
|
|
27144
27503
|
});
|
|
27145
27504
|
|
|
27146
27505
|
// src/ai/strategist-prompt.ts
|
|
27147
|
-
function
|
|
27506
|
+
function companyContextSection4() {
|
|
27148
27507
|
const block = buildCompanyProfileBlock();
|
|
27149
27508
|
if (!block) return "";
|
|
27150
27509
|
return `COMPANY CONTEXT (ground every constraint, timeline, and dollar figure in this business):
|
|
@@ -27152,7 +27511,7 @@ ${block}
|
|
|
27152
27511
|
|
|
27153
27512
|
`;
|
|
27154
27513
|
}
|
|
27155
|
-
function
|
|
27514
|
+
function operatorSection4() {
|
|
27156
27515
|
const block = buildOperatorBlock();
|
|
27157
27516
|
if (!block) return "";
|
|
27158
27517
|
return `${block}
|
|
@@ -27164,7 +27523,7 @@ function buildStrategistSystemPrompt(todayIso) {
|
|
|
27164
27523
|
|
|
27165
27524
|
Today's date is ${todayIso}. All milestone and check dates must be real future calendar dates computed from today.
|
|
27166
27525
|
|
|
27167
|
-
${
|
|
27526
|
+
${companyContextSection4()}${operatorSection4()}HOW YOU THINK (the strategist method \u2014 reverse operator thinking):
|
|
27168
27527
|
1. DEFINE THE DESTINATION. A strategy starts from a measurable objective, not from a list of problems.
|
|
27169
27528
|
2. GROUND IN VERIFIED REALITY. Every number you use must come from a tool call or provided context. If you didn't verify it, it is an assumption and must be labeled as one.
|
|
27170
27529
|
3. BACKCAST THE DEPENDENCY CHAIN. Work backwards from the objective: what must be true immediately before it holds? And before that? Sequence by dependency, not by severity.
|
|
@@ -30053,13 +30412,36 @@ __export(activate_exports, {
|
|
|
30053
30412
|
handler: () => handler23
|
|
30054
30413
|
});
|
|
30055
30414
|
import chalk45 from "chalk";
|
|
30415
|
+
async function afterLicenseSuccess(ctx) {
|
|
30416
|
+
if (ctx.oneShot) return;
|
|
30417
|
+
const { resumeSetupAfterLicense: resumeSetupAfterLicense2 } = await Promise.resolve().then(() => (init_first_run(), first_run_exports));
|
|
30418
|
+
await resumeSetupAfterLicense2(ctx);
|
|
30419
|
+
}
|
|
30056
30420
|
async function handler23(args, ctx) {
|
|
30057
30421
|
const { positional } = parseArgs2(args);
|
|
30058
30422
|
const key = positional[0];
|
|
30059
30423
|
if (!key) {
|
|
30060
|
-
|
|
30061
|
-
|
|
30062
|
-
|
|
30424
|
+
if (ctx.oneShot || !process.stdin.isTTY) {
|
|
30425
|
+
console.error(chalk45.red("\n Usage: /activate <key>"));
|
|
30426
|
+
console.error(chalk45.dim(" Or type /activate in ntrp to paste a key.\n"));
|
|
30427
|
+
if (ctx.oneShot) process.exit(1);
|
|
30428
|
+
return;
|
|
30429
|
+
}
|
|
30430
|
+
if (hasValidLicense()) {
|
|
30431
|
+
console.log();
|
|
30432
|
+
console.log(chalk45.green(" A license is already active."));
|
|
30433
|
+
console.log();
|
|
30434
|
+
await afterLicenseSuccess(ctx);
|
|
30435
|
+
return;
|
|
30436
|
+
}
|
|
30437
|
+
console.log();
|
|
30438
|
+
console.log(
|
|
30439
|
+
" " + chalk45.dim("Paste a trial key or a Pro key. Type ") + paint("accent", "/checkout") + chalk45.dim(" if you need to sign up.")
|
|
30440
|
+
);
|
|
30441
|
+
console.log();
|
|
30442
|
+
const activated = await promptForLicenseKey(ctx);
|
|
30443
|
+
if (!activated) return;
|
|
30444
|
+
await afterLicenseSuccess(ctx);
|
|
30063
30445
|
return;
|
|
30064
30446
|
}
|
|
30065
30447
|
try {
|
|
@@ -30074,10 +30456,7 @@ async function handler23(args, ctx) {
|
|
|
30074
30456
|
console.log(chalk45.green(`
|
|
30075
30457
|
License activated: ${result.message}
|
|
30076
30458
|
`));
|
|
30077
|
-
|
|
30078
|
-
const { replayPendingBlockedLine: replayPendingBlockedLine2 } = await Promise.resolve().then(() => (init_dispatch(), dispatch_exports));
|
|
30079
|
-
await replayPendingBlockedLine2(ctx);
|
|
30080
|
-
}
|
|
30459
|
+
await afterLicenseSuccess(ctx);
|
|
30081
30460
|
} catch (err) {
|
|
30082
30461
|
const message = err instanceof Error ? err.message : "License activation failed";
|
|
30083
30462
|
console.error(chalk45.red(`
|
|
@@ -30092,6 +30471,9 @@ var init_activate = __esm({
|
|
|
30092
30471
|
"use strict";
|
|
30093
30472
|
init_verify();
|
|
30094
30473
|
init_argparse();
|
|
30474
|
+
init_activation();
|
|
30475
|
+
init_upgrade();
|
|
30476
|
+
init_theme();
|
|
30095
30477
|
}
|
|
30096
30478
|
});
|
|
30097
30479
|
|
|
@@ -30130,8 +30512,8 @@ async function handler24(args, ctx) {
|
|
|
30130
30512
|
return;
|
|
30131
30513
|
}
|
|
30132
30514
|
if (!ctx.oneShot) {
|
|
30133
|
-
const {
|
|
30134
|
-
await
|
|
30515
|
+
const { resumeSetupAfterLicense: resumeSetupAfterLicense2 } = await Promise.resolve().then(() => (init_first_run(), first_run_exports));
|
|
30516
|
+
await resumeSetupAfterLicense2(ctx);
|
|
30135
30517
|
}
|
|
30136
30518
|
}
|
|
30137
30519
|
var init_upgrade2 = __esm({
|
|
@@ -30159,7 +30541,7 @@ var init_checkout = __esm({
|
|
|
30159
30541
|
});
|
|
30160
30542
|
|
|
30161
30543
|
// src/services/setup.ts
|
|
30162
|
-
import { existsSync as
|
|
30544
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync17, readFileSync as readFileSync20, writeFileSync as writeFileSync19 } from "fs";
|
|
30163
30545
|
import { join as join29 } from "path";
|
|
30164
30546
|
function setupCheck() {
|
|
30165
30547
|
const home = ntrpHome();
|
|
@@ -32157,7 +32539,7 @@ __export(sessions_exports, {
|
|
|
32157
32539
|
handler: () => handler35
|
|
32158
32540
|
});
|
|
32159
32541
|
import chalk61 from "chalk";
|
|
32160
|
-
import { existsSync as
|
|
32542
|
+
import { existsSync as existsSync28 } from "fs";
|
|
32161
32543
|
async function handler35(args, _ctx) {
|
|
32162
32544
|
const sub = args[0] ?? "list";
|
|
32163
32545
|
if (sub === "list" || !args[0]) {
|
|
@@ -32264,12 +32646,12 @@ function showSession(idArg) {
|
|
|
32264
32646
|
console.log();
|
|
32265
32647
|
const transcriptPath = transcriptPathForSession(session.id);
|
|
32266
32648
|
const contextPath = contextDocPathForSession(session.id);
|
|
32267
|
-
if (
|
|
32649
|
+
if (existsSync28(transcriptPath) || existsSync28(contextPath)) {
|
|
32268
32650
|
console.log(" " + chalk61.dim("\u2500".repeat(40)));
|
|
32269
|
-
if (
|
|
32651
|
+
if (existsSync28(contextPath)) {
|
|
32270
32652
|
console.log(" " + chalk61.dim("Context brief: ") + chalk61.dim(contextPath));
|
|
32271
32653
|
}
|
|
32272
|
-
if (
|
|
32654
|
+
if (existsSync28(transcriptPath)) {
|
|
32273
32655
|
console.log(" " + chalk61.dim("Full transcript: ") + chalk61.dim(transcriptPath));
|
|
32274
32656
|
}
|
|
32275
32657
|
console.log();
|
|
@@ -32549,39 +32931,368 @@ var init_privacy_notice = __esm({
|
|
|
32549
32931
|
}
|
|
32550
32932
|
});
|
|
32551
32933
|
|
|
32934
|
+
// src/services/think.ts
|
|
32935
|
+
var think_exports = {};
|
|
32936
|
+
__export(think_exports, {
|
|
32937
|
+
runThinkTurn: () => runThinkTurn
|
|
32938
|
+
});
|
|
32939
|
+
import chalk65 from "chalk";
|
|
32940
|
+
async function runThinkTurn(input, ctx) {
|
|
32941
|
+
assertReplAi(ctx);
|
|
32942
|
+
let snapshot = ctx.snapshot.computeResult;
|
|
32943
|
+
if (!snapshot) {
|
|
32944
|
+
const metricsFirst = prefersMetricsFirstContext(ctx);
|
|
32945
|
+
const spinner2 = makeSpinner(metricsFirst ? "Loading session context\u2026" : "Computing vital signs\u2026");
|
|
32946
|
+
try {
|
|
32947
|
+
snapshot = await computeFullHealth();
|
|
32948
|
+
ctx.snapshot.computeResult = snapshot;
|
|
32949
|
+
const divInput = snapshot.segments.map((s) => ({
|
|
32950
|
+
segmentId: s.segment.id,
|
|
32951
|
+
segmentName: s.segment.name,
|
|
32952
|
+
result: s.result
|
|
32953
|
+
}));
|
|
32954
|
+
ctx.snapshot.divergences = detectDivergences(snapshot.aggregate, divInput).divergences;
|
|
32955
|
+
spinner2.succeed(metricsFirst ? "Session context ready" : "Health snapshot ready");
|
|
32956
|
+
} catch (err) {
|
|
32957
|
+
spinner2.fail("Could not compute health snapshot");
|
|
32958
|
+
console.error(" " + chalk65.red(String(err.message ?? err)));
|
|
32959
|
+
console.log(" " + chalk65.dim("Run ") + paint("accent", "/new") + chalk65.dim(" \u2192 pick Demo to load sample data."));
|
|
32960
|
+
console.log();
|
|
32961
|
+
return;
|
|
32962
|
+
}
|
|
32963
|
+
}
|
|
32964
|
+
console.log();
|
|
32965
|
+
const memoryBlock = await buildMemoryBlock(input).catch(() => "");
|
|
32966
|
+
const spinner = makeSpinner("Thinking with you\u2026");
|
|
32967
|
+
let lastAnswer = "";
|
|
32968
|
+
let rawHistory = [];
|
|
32969
|
+
const toolsUsed = [];
|
|
32970
|
+
setAgentContext(ctx);
|
|
32971
|
+
try {
|
|
32972
|
+
const analysisBlock = buildAnalysisBlock(ctx);
|
|
32973
|
+
const conversationBlock = getConversationPhaseBlock(ctx);
|
|
32974
|
+
const bundle = await loadSessionAnalysisBundle();
|
|
32975
|
+
const sessionArtifact = hasAnyAnalysis(bundle) ? buildExploreContextBlock(bundle, ctx) : "";
|
|
32976
|
+
for await (const event of agenticFindings(snapshot, ctx.snapshot.divergences, {
|
|
32977
|
+
mode: "think",
|
|
32978
|
+
userQuestion: input,
|
|
32979
|
+
sessionContext: ctx.resumedSessionSummary,
|
|
32980
|
+
includeMetrics: true,
|
|
32981
|
+
analysisBlock,
|
|
32982
|
+
conversationBlock,
|
|
32983
|
+
sessionArtifact,
|
|
32984
|
+
priorMessages: ctx.thinkConversation,
|
|
32985
|
+
memoryBlock,
|
|
32986
|
+
ctx
|
|
32987
|
+
})) {
|
|
32988
|
+
switch (event.type) {
|
|
32989
|
+
case "tool_call":
|
|
32990
|
+
toolsUsed.push(event.name);
|
|
32991
|
+
spinner.text = `Querying ${event.name}\u2026`;
|
|
32992
|
+
break;
|
|
32993
|
+
case "thinking":
|
|
32994
|
+
spinner.stop();
|
|
32995
|
+
console.log(" " + chalk65.dim.italic(event.text));
|
|
32996
|
+
spinner.start("Thinking with you\u2026");
|
|
32997
|
+
break;
|
|
32998
|
+
case "answer":
|
|
32999
|
+
spinner.stop();
|
|
33000
|
+
lastAnswer = event.text;
|
|
33001
|
+
printMarkdown(event.text, { indent: 2 });
|
|
33002
|
+
break;
|
|
33003
|
+
case "finding":
|
|
33004
|
+
spinner.stop();
|
|
33005
|
+
printFindingInline2(event.finding);
|
|
33006
|
+
break;
|
|
33007
|
+
case "done":
|
|
33008
|
+
spinner.stop();
|
|
33009
|
+
rawHistory = event.conversation_history;
|
|
33010
|
+
break;
|
|
33011
|
+
}
|
|
33012
|
+
}
|
|
33013
|
+
} catch (err) {
|
|
33014
|
+
spinner.fail("Error while thinking");
|
|
33015
|
+
console.error(" " + chalk65.red(String(err.message ?? err)));
|
|
33016
|
+
console.log();
|
|
33017
|
+
return;
|
|
33018
|
+
} finally {
|
|
33019
|
+
setAgentContext(null);
|
|
33020
|
+
}
|
|
33021
|
+
if (rawHistory.length > 0) {
|
|
33022
|
+
ctx.thinkConversation = distillThread(rawHistory);
|
|
33023
|
+
}
|
|
33024
|
+
if (!lastAnswer) {
|
|
33025
|
+
console.log(" " + chalk65.dim("(no answer returned)"));
|
|
33026
|
+
} else {
|
|
33027
|
+
recordMessage(ctx, "agent", lastAnswer);
|
|
33028
|
+
saveSessionState(ctx);
|
|
33029
|
+
creditNlAnswer(ctx, Math.floor(ctx.messages.length / 2));
|
|
33030
|
+
recordAnalysis({
|
|
33031
|
+
question: `[think] ${input}`,
|
|
33032
|
+
answer: lastAnswer,
|
|
33033
|
+
tools: toolsUsed,
|
|
33034
|
+
session_id: ctx.sessionId
|
|
33035
|
+
});
|
|
33036
|
+
ctx.lastExchange = { question: input, answer: lastAnswer };
|
|
33037
|
+
}
|
|
33038
|
+
console.log();
|
|
33039
|
+
return lastAnswer ? extractSummary2(lastAnswer) : void 0;
|
|
33040
|
+
}
|
|
33041
|
+
function extractSummary2(text) {
|
|
33042
|
+
const plain = text.replace(/#{1,6}\s+/g, "").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^[-*]\s+/gm, "").trim();
|
|
33043
|
+
const sentenceMatch = plain.match(/^(.+?[.!?])(?:\s|$)/);
|
|
33044
|
+
const sentence = sentenceMatch ? sentenceMatch[1] : plain.split("\n")[0];
|
|
33045
|
+
if (sentence.length <= 60) return sentence;
|
|
33046
|
+
return sentence.slice(0, 60).replace(/\s+\S*$/, "") + "\u2026";
|
|
33047
|
+
}
|
|
33048
|
+
function printFindingInline2(finding) {
|
|
33049
|
+
const sev = finding.severity;
|
|
33050
|
+
console.log();
|
|
33051
|
+
console.log(
|
|
33052
|
+
" " + severityPaint(sev)(sev.toUpperCase()) + " " + (finding.finding ?? "").slice(0, 120)
|
|
33053
|
+
);
|
|
33054
|
+
}
|
|
33055
|
+
var init_think = __esm({
|
|
33056
|
+
"src/services/think.ts"() {
|
|
33057
|
+
"use strict";
|
|
33058
|
+
init_spinner();
|
|
33059
|
+
init_context2();
|
|
33060
|
+
init_phase();
|
|
33061
|
+
init_agent_context();
|
|
33062
|
+
init_agentic_loop();
|
|
33063
|
+
init_thread();
|
|
33064
|
+
init_store2();
|
|
33065
|
+
init_health_score();
|
|
33066
|
+
init_divergence();
|
|
33067
|
+
init_repl_api();
|
|
33068
|
+
init_theme();
|
|
33069
|
+
init_markdown();
|
|
33070
|
+
init_session_analysis();
|
|
33071
|
+
init_time_bank();
|
|
33072
|
+
}
|
|
33073
|
+
});
|
|
33074
|
+
|
|
33075
|
+
// src/conversation/think-flow.ts
|
|
33076
|
+
var think_flow_exports = {};
|
|
33077
|
+
__export(think_flow_exports, {
|
|
33078
|
+
clearThinkFlow: () => clearThinkFlow,
|
|
33079
|
+
extractThinkSeed: () => extractThinkSeed,
|
|
33080
|
+
handleThinkFlow: () => handleThinkFlow,
|
|
33081
|
+
isThinkIntent: () => isThinkIntent,
|
|
33082
|
+
queueThinkForAnalysis: () => queueThinkForAnalysis,
|
|
33083
|
+
resumeThinkAfterCompute: () => resumeThinkAfterCompute,
|
|
33084
|
+
resumeThinkAfterConnect: () => resumeThinkAfterConnect,
|
|
33085
|
+
startThinkFlow: () => startThinkFlow
|
|
33086
|
+
});
|
|
33087
|
+
import chalk66 from "chalk";
|
|
33088
|
+
function isThinkIntent(input) {
|
|
33089
|
+
const line = input.trim();
|
|
33090
|
+
if (!line) return false;
|
|
33091
|
+
if (isShipIntent(line)) return false;
|
|
33092
|
+
if (isStrategistIntent(line)) return false;
|
|
33093
|
+
return THINK_INTENT_RE.test(line);
|
|
33094
|
+
}
|
|
33095
|
+
function extractThinkSeed(input) {
|
|
33096
|
+
const cleaned = input.trim().replace(/^(hey|ok|okay|please|can you|could you|help me|let'?s|i want to|i'?d like to)\s+/i, "").replace(/^(think\s+with\s+me|pressure[- ]?test|dig\s+into|think\s+through)\s*(about|on|around|this|:)?\s*/i, "").replace(/^(what\s+am\s+i\s+missing\s*(about|on|with|here)?)\s*/i, "").trim();
|
|
33097
|
+
return cleaned.length >= 4 ? cleaned : input.trim();
|
|
33098
|
+
}
|
|
33099
|
+
function queueThinkForAnalysis(ctx, opts) {
|
|
33100
|
+
ctx.thinkState = {
|
|
33101
|
+
step: "awaiting_analysis",
|
|
33102
|
+
seed: opts.seed,
|
|
33103
|
+
origin: opts.origin,
|
|
33104
|
+
started_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
33105
|
+
};
|
|
33106
|
+
saveSessionState(ctx);
|
|
33107
|
+
console.log();
|
|
33108
|
+
console.log(
|
|
33109
|
+
" " + chalk66.dim("Think session queued. NTRP opens the channel after analysis.")
|
|
33110
|
+
);
|
|
33111
|
+
if (opts.origin !== "nl") {
|
|
33112
|
+
console.log(
|
|
33113
|
+
" " + chalk66.dim("Type what to look at. Paste a CSV path. Or type ") + chalk66.cyan("use demo data") + chalk66.dim(".")
|
|
33114
|
+
);
|
|
33115
|
+
}
|
|
33116
|
+
console.log();
|
|
33117
|
+
}
|
|
33118
|
+
function printChannelIntro(seed) {
|
|
33119
|
+
console.log();
|
|
33120
|
+
console.log(" " + paint("accent", "Think with me"));
|
|
33121
|
+
console.log(
|
|
33122
|
+
" " + chalk66.dim(
|
|
33123
|
+
"Socratic channel \u2014 explore, challenge assumptions, pull evidence. Type "
|
|
33124
|
+
) + chalk66.cyan("done") + chalk66.dim(" or ") + chalk66.cyan("cancel") + chalk66.dim(" to return to ask \u203A.")
|
|
33125
|
+
);
|
|
33126
|
+
if (seed) {
|
|
33127
|
+
console.log(" " + chalk66.dim("Seed: ") + seed);
|
|
33128
|
+
}
|
|
33129
|
+
console.log();
|
|
33130
|
+
}
|
|
33131
|
+
function armKeylessThink(ctx, opts) {
|
|
33132
|
+
ctx.thinkState = {
|
|
33133
|
+
step: "awaiting_connect",
|
|
33134
|
+
seed: opts.seed,
|
|
33135
|
+
origin: opts.origin,
|
|
33136
|
+
started_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
33137
|
+
};
|
|
33138
|
+
saveSessionState(ctx);
|
|
33139
|
+
console.log();
|
|
33140
|
+
console.log(" " + chalk66.dim("Think channel needs an AI key."));
|
|
33141
|
+
console.log(
|
|
33142
|
+
" " + chalk66.dim("Type ") + paint("accent", "/connect") + chalk66.dim(" and paste a key. Seed kept \u2014 the channel opens after connect.")
|
|
33143
|
+
);
|
|
33144
|
+
console.log();
|
|
33145
|
+
}
|
|
33146
|
+
async function startThinkFlow(ctx, opts) {
|
|
33147
|
+
if (!isAnalysisReady(ctx)) {
|
|
33148
|
+
queueThinkForAnalysis(ctx, opts);
|
|
33149
|
+
return "Think queued";
|
|
33150
|
+
}
|
|
33151
|
+
if (!canUseReplAi(ctx)) {
|
|
33152
|
+
armKeylessThink(ctx, opts);
|
|
33153
|
+
return "Think awaiting connect";
|
|
33154
|
+
}
|
|
33155
|
+
const seed = opts.seed?.trim() || void 0;
|
|
33156
|
+
ctx.thinkState = {
|
|
33157
|
+
step: "active",
|
|
33158
|
+
seed,
|
|
33159
|
+
origin: opts.origin,
|
|
33160
|
+
started_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
33161
|
+
open_questions: [],
|
|
33162
|
+
challenged_assumptions: [],
|
|
33163
|
+
working_hypotheses: []
|
|
33164
|
+
};
|
|
33165
|
+
if (ctx.thinkConversation.length === 0 && seed) {
|
|
33166
|
+
}
|
|
33167
|
+
saveSessionState(ctx);
|
|
33168
|
+
printChannelIntro(seed);
|
|
33169
|
+
recordMessage(ctx, "agent", seed ? `Think channel opened: ${seed}` : "Think channel opened");
|
|
33170
|
+
if (seed) {
|
|
33171
|
+
recordMessage(ctx, "user", seed);
|
|
33172
|
+
const { runThinkTurn: runThinkTurn2 } = await Promise.resolve().then(() => (init_think(), think_exports));
|
|
33173
|
+
await runThinkTurn2(seed, ctx);
|
|
33174
|
+
}
|
|
33175
|
+
return "Think channel open";
|
|
33176
|
+
}
|
|
33177
|
+
async function resumeThinkAfterCompute(ctx) {
|
|
33178
|
+
const state2 = ctx.thinkState;
|
|
33179
|
+
if (!state2 || state2.step !== "awaiting_analysis") return;
|
|
33180
|
+
if (ctx.strategistState && ctx.strategistState.step !== "awaiting_analysis" && ctx.strategistState.step !== "awaiting_connect") {
|
|
33181
|
+
return;
|
|
33182
|
+
}
|
|
33183
|
+
if (ctx.strategistState?.step === "awaiting_analysis") return;
|
|
33184
|
+
console.log();
|
|
33185
|
+
console.log(" " + paint("accent", "Analysis is ready. The think channel continues."));
|
|
33186
|
+
await startThinkFlow(ctx, {
|
|
33187
|
+
seed: state2.seed,
|
|
33188
|
+
origin: state2.origin ?? "nl"
|
|
33189
|
+
});
|
|
33190
|
+
}
|
|
33191
|
+
async function resumeThinkAfterConnect(ctx) {
|
|
33192
|
+
const state2 = ctx.thinkState;
|
|
33193
|
+
if (!state2 || state2.step !== "awaiting_connect") return false;
|
|
33194
|
+
if (!canUseReplAi(ctx)) return false;
|
|
33195
|
+
console.log();
|
|
33196
|
+
console.log(" " + paint("accent", "Key connected. Opening the think channel."));
|
|
33197
|
+
await startThinkFlow(ctx, {
|
|
33198
|
+
seed: state2.seed,
|
|
33199
|
+
origin: state2.origin ?? "nl"
|
|
33200
|
+
});
|
|
33201
|
+
return true;
|
|
33202
|
+
}
|
|
33203
|
+
function clearThinkFlow(ctx, reason) {
|
|
33204
|
+
ctx.thinkState = void 0;
|
|
33205
|
+
saveSessionState(ctx);
|
|
33206
|
+
if (reason === "handoff") return;
|
|
33207
|
+
console.log();
|
|
33208
|
+
console.log(
|
|
33209
|
+
" " + chalk66.dim(
|
|
33210
|
+
reason === "done" ? "Think channel closed. Back to ask \u203A." : "Think session cancelled. Continue exploration."
|
|
33211
|
+
)
|
|
33212
|
+
);
|
|
33213
|
+
console.log();
|
|
33214
|
+
}
|
|
33215
|
+
async function handleThinkFlow(input, ctx) {
|
|
33216
|
+
const state2 = ctx.thinkState;
|
|
33217
|
+
if (!state2 || state2.step !== "active") return;
|
|
33218
|
+
const line = input.trim();
|
|
33219
|
+
recordMessage(ctx, "user", line);
|
|
33220
|
+
if (CANCEL_RE2.test(line) || DONE_RE.test(line)) {
|
|
33221
|
+
clearThinkFlow(ctx, CANCEL_RE2.test(line) ? "cancel" : "done");
|
|
33222
|
+
recordMessage(ctx, "agent", "Think channel closed");
|
|
33223
|
+
return "Think closed";
|
|
33224
|
+
}
|
|
33225
|
+
if (isStrategistIntent(line)) {
|
|
33226
|
+
clearThinkFlow(ctx, "handoff");
|
|
33227
|
+
const summary = await startStrategistFlow(ctx, {
|
|
33228
|
+
seed: extractObjectiveSeed(line),
|
|
33229
|
+
origin: "nl"
|
|
33230
|
+
}) ?? void 0;
|
|
33231
|
+
return summary ?? "Handed off to strategist";
|
|
33232
|
+
}
|
|
33233
|
+
if (!canUseReplAi(ctx)) {
|
|
33234
|
+
armKeylessThink(ctx, { seed: state2.seed ?? line, origin: state2.origin ?? "nl" });
|
|
33235
|
+
return "Think awaiting connect";
|
|
33236
|
+
}
|
|
33237
|
+
const { runThinkTurn: runThinkTurn2 } = await Promise.resolve().then(() => (init_think(), think_exports));
|
|
33238
|
+
await runThinkTurn2(line, ctx);
|
|
33239
|
+
if (ctx.strategistState && ctx.strategistState.step !== "awaiting_analysis" && ctx.strategistState.step !== "awaiting_connect") {
|
|
33240
|
+
clearThinkFlow(ctx, "handoff");
|
|
33241
|
+
const { promptQueuedAiStrategist: promptQueuedAiStrategist2 } = await Promise.resolve().then(() => (init_strategist_flow(), strategist_flow_exports));
|
|
33242
|
+
promptQueuedAiStrategist2(ctx);
|
|
33243
|
+
}
|
|
33244
|
+
return "Think turn";
|
|
33245
|
+
}
|
|
33246
|
+
var THINK_INTENT_RE, CANCEL_RE2, DONE_RE;
|
|
33247
|
+
var init_think_flow = __esm({
|
|
33248
|
+
"src/conversation/think-flow.ts"() {
|
|
33249
|
+
"use strict";
|
|
33250
|
+
init_context2();
|
|
33251
|
+
init_repl_api();
|
|
33252
|
+
init_theme();
|
|
33253
|
+
init_handoff_draft();
|
|
33254
|
+
init_strategist_flow();
|
|
33255
|
+
THINK_INTENT_RE = /\b(think\s+with\s+me|pressure[- ]?test|what\s+am\s+i\s+missing|challenge\s+(my\s+)?(assumption|thinking|hypothesis)|let'?s\s+(dig|explore|think|pressure)|dig\s+into|steelman|devil'?s\s+advocate|think\s+through|brainstorm\s+(with\s+me|this)|socratic)\b/i;
|
|
33256
|
+
CANCEL_RE2 = /^(cancel|stop|quit|abort|never\s?mind|nevermind|forget it)\s*[.!]?\s*$/i;
|
|
33257
|
+
DONE_RE = /^(done|enough|enough for now|that'?s enough|leave|exit think)\s*[.!]?\s*$/i;
|
|
33258
|
+
}
|
|
33259
|
+
});
|
|
33260
|
+
|
|
32552
33261
|
// src/commands/connect.ts
|
|
32553
33262
|
var connect_exports2 = {};
|
|
32554
33263
|
__export(connect_exports2, {
|
|
32555
33264
|
handler: () => handler39
|
|
32556
33265
|
});
|
|
32557
|
-
import
|
|
33266
|
+
import chalk67 from "chalk";
|
|
32558
33267
|
function usage2() {
|
|
32559
|
-
console.log(
|
|
32560
|
-
console.log(
|
|
32561
|
-
console.log(
|
|
32562
|
-
console.log(
|
|
33268
|
+
console.log(chalk67.dim(" Paste a key inside ntrp. Type /connect and press Enter."));
|
|
33269
|
+
console.log(chalk67.dim(" Scripts: ntrp connect --key <key>"));
|
|
33270
|
+
console.log(chalk67.dim(" Named provider: /connect anthropic (or ollama, no key)"));
|
|
33271
|
+
console.log(chalk67.dim(" Custom endpoint (scripts): --base-url <url> [--id <name>]"));
|
|
32563
33272
|
}
|
|
32564
33273
|
function printOutcome(outcome, ctx) {
|
|
32565
33274
|
console.log();
|
|
32566
33275
|
const [headline, ...rest] = describeConnectOutcome(outcome);
|
|
32567
|
-
console.log(" " + paint("success", "\u2713") + " " +
|
|
33276
|
+
console.log(" " + paint("success", "\u2713") + " " + chalk67.bold(headline ?? ""));
|
|
32568
33277
|
for (const line of rest) {
|
|
32569
|
-
console.log(" " +
|
|
33278
|
+
console.log(" " + chalk67.dim(line));
|
|
32570
33279
|
}
|
|
32571
33280
|
console.log();
|
|
32572
|
-
console.log(" " +
|
|
32573
|
-
console.log(" " +
|
|
33281
|
+
console.log(" " + chalk67.dim(`Using ${formatActiveStack(ctx)}`));
|
|
33282
|
+
console.log(" " + chalk67.dim("Type a question to try it. Type /provider to switch providers."));
|
|
32574
33283
|
console.log();
|
|
32575
|
-
console.log(" " +
|
|
33284
|
+
console.log(" " + chalk67.dim("What leaves this machine"));
|
|
32576
33285
|
for (const line of PRIVACY_NOTICE_LINES.slice(0, 8)) {
|
|
32577
|
-
console.log(" " +
|
|
33286
|
+
console.log(" " + chalk67.dim(line));
|
|
32578
33287
|
}
|
|
32579
|
-
console.log(" " +
|
|
33288
|
+
console.log(" " + chalk67.dim("Type /privacy to read the full notice."));
|
|
32580
33289
|
console.log();
|
|
32581
33290
|
}
|
|
32582
33291
|
async function replayAfterConnect(ctx) {
|
|
32583
33292
|
const { resumeStrategistAfterConnect: resumeStrategistAfterConnect2 } = await Promise.resolve().then(() => (init_strategist_flow(), strategist_flow_exports));
|
|
32584
33293
|
if (await resumeStrategistAfterConnect2(ctx)) return;
|
|
33294
|
+
const { resumeThinkAfterConnect: resumeThinkAfterConnect2 } = await Promise.resolve().then(() => (init_think_flow(), think_flow_exports));
|
|
33295
|
+
if (await resumeThinkAfterConnect2(ctx)) return;
|
|
32585
33296
|
if (!ctx.pendingAsk?.text) return;
|
|
32586
33297
|
const { isAnalysisReady: isAnalysisReady2 } = await Promise.resolve().then(() => (init_context2(), context_exports));
|
|
32587
33298
|
if (!isAnalysisReady2(ctx)) return;
|
|
@@ -32591,14 +33302,14 @@ async function replayAfterConnect(ctx) {
|
|
|
32591
33302
|
function printError(err, ctx) {
|
|
32592
33303
|
const message = err instanceof Error ? err.message : String(err);
|
|
32593
33304
|
console.log();
|
|
32594
|
-
console.log(" " +
|
|
33305
|
+
console.log(" " + chalk67.red(message));
|
|
32595
33306
|
console.log();
|
|
32596
33307
|
if (ctx.oneShot) process.exit(1);
|
|
32597
33308
|
}
|
|
32598
33309
|
async function promptKey(session, label, opts = {}) {
|
|
32599
33310
|
console.log();
|
|
32600
33311
|
console.log(
|
|
32601
|
-
" " +
|
|
33312
|
+
" " + chalk67.dim("Paste once, press Enter. Stored in ") + paint("accent", "~/.ntrp/config.json") + chalk67.dim(" only.")
|
|
32602
33313
|
);
|
|
32603
33314
|
return session.askSecret(label, { confirm: false, allowEmpty: opts.allowEmpty });
|
|
32604
33315
|
}
|
|
@@ -32631,7 +33342,7 @@ async function handler39(args, ctx) {
|
|
|
32631
33342
|
if (baseUrl && !forcedSpec) {
|
|
32632
33343
|
const id = customId ?? forcedProvider ?? hostToId(baseUrl);
|
|
32633
33344
|
for (const warning of customEndpointWarnings(baseUrl)) {
|
|
32634
|
-
console.log(" " +
|
|
33345
|
+
console.log(" " + chalk67.yellow(warning));
|
|
32635
33346
|
}
|
|
32636
33347
|
let key2 = inlineKey;
|
|
32637
33348
|
if (!key2 && !ctx.oneShot && process.stdin.isTTY) {
|
|
@@ -32642,7 +33353,7 @@ async function handler39(args, ctx) {
|
|
|
32642
33353
|
true
|
|
32643
33354
|
);
|
|
32644
33355
|
if (!proceed) {
|
|
32645
|
-
console.log(" " +
|
|
33356
|
+
console.log(" " + chalk67.dim("Cancelled."));
|
|
32646
33357
|
console.log();
|
|
32647
33358
|
return;
|
|
32648
33359
|
}
|
|
@@ -32650,7 +33361,7 @@ async function handler39(args, ctx) {
|
|
|
32650
33361
|
if (needsKey) key2 = await promptKey(session2, `API key for ${id}`);
|
|
32651
33362
|
} catch (err) {
|
|
32652
33363
|
if (err instanceof Error && err.message === "Cancelled") {
|
|
32653
|
-
console.log(" " +
|
|
33364
|
+
console.log(" " + chalk67.dim("Cancelled."));
|
|
32654
33365
|
console.log();
|
|
32655
33366
|
return;
|
|
32656
33367
|
}
|
|
@@ -32673,11 +33384,11 @@ async function handler39(args, ctx) {
|
|
|
32673
33384
|
}
|
|
32674
33385
|
if (forcedProvider && !forcedSpec) {
|
|
32675
33386
|
console.log();
|
|
32676
|
-
console.log(" " +
|
|
33387
|
+
console.log(" " + chalk67.red(`Unknown provider: ${forcedProvider}`));
|
|
32677
33388
|
console.log(
|
|
32678
|
-
" " +
|
|
33389
|
+
" " + chalk67.dim("Built-ins: anthropic, openai, google, groq, mistral, deepseek, xai, openrouter, together, fireworks, ollama")
|
|
32679
33390
|
);
|
|
32680
|
-
console.log(" " +
|
|
33391
|
+
console.log(" " + chalk67.dim(`Custom endpoint: /connect --base-url <url> --id ${forcedProvider}`));
|
|
32681
33392
|
console.log();
|
|
32682
33393
|
if (ctx.oneShot) process.exit(1);
|
|
32683
33394
|
return;
|
|
@@ -32700,7 +33411,7 @@ async function handler39(args, ctx) {
|
|
|
32700
33411
|
} catch (err) {
|
|
32701
33412
|
session.close();
|
|
32702
33413
|
if (err instanceof Error && err.message === "Cancelled") {
|
|
32703
|
-
console.log(" " +
|
|
33414
|
+
console.log(" " + chalk67.dim("Cancelled."));
|
|
32704
33415
|
console.log();
|
|
32705
33416
|
return;
|
|
32706
33417
|
}
|
|
@@ -32708,7 +33419,7 @@ async function handler39(args, ctx) {
|
|
|
32708
33419
|
}
|
|
32709
33420
|
if (!key) {
|
|
32710
33421
|
session.close();
|
|
32711
|
-
console.log(" " +
|
|
33422
|
+
console.log(" " + chalk67.dim("No key pasted \u2014 cancelled. Run ") + paint("accent", "/connect") + chalk67.dim(" when you have one."));
|
|
32712
33423
|
console.log();
|
|
32713
33424
|
return;
|
|
32714
33425
|
}
|
|
@@ -32738,7 +33449,7 @@ async function handler39(args, ctx) {
|
|
|
32738
33449
|
} catch (err) {
|
|
32739
33450
|
spinner.stop();
|
|
32740
33451
|
if (err instanceof ConnectCancelled) {
|
|
32741
|
-
console.log(" " +
|
|
33452
|
+
console.log(" " + chalk67.dim("Cancelled."));
|
|
32742
33453
|
console.log();
|
|
32743
33454
|
} else {
|
|
32744
33455
|
printError(err, ctx);
|
|
@@ -32774,7 +33485,7 @@ var provider_exports = {};
|
|
|
32774
33485
|
__export(provider_exports, {
|
|
32775
33486
|
handler: () => handler40
|
|
32776
33487
|
});
|
|
32777
|
-
import
|
|
33488
|
+
import chalk68 from "chalk";
|
|
32778
33489
|
async function handler40(args, ctx) {
|
|
32779
33490
|
const { positional, flags } = parseArgs2(args, ["default"]);
|
|
32780
33491
|
const sub = positional[0]?.toLowerCase();
|
|
@@ -32787,7 +33498,7 @@ async function handler40(args, ctx) {
|
|
|
32787
33498
|
if (!ctx.oneShot) saveSessionState(ctx);
|
|
32788
33499
|
console.log();
|
|
32789
33500
|
console.log(" " + paint("success", "\u2713") + " Session engine reset \u2014 using config defaults.");
|
|
32790
|
-
console.log(" " +
|
|
33501
|
+
console.log(" " + chalk68.dim(`Default: ${loadLlmConfig().primary}`));
|
|
32791
33502
|
console.log();
|
|
32792
33503
|
return;
|
|
32793
33504
|
}
|
|
@@ -32800,7 +33511,7 @@ async function handler40(args, ctx) {
|
|
|
32800
33511
|
setConfigValue("llm-auto-failover", session.autoFailover ? "on" : "off");
|
|
32801
33512
|
}
|
|
32802
33513
|
console.log();
|
|
32803
|
-
console.log(" " + paint("success", "\u2713") + ` Saved ${
|
|
33514
|
+
console.log(" " + paint("success", "\u2713") + ` Saved ${chalk68.bold(active)} as default engine.`);
|
|
32804
33515
|
console.log();
|
|
32805
33516
|
return;
|
|
32806
33517
|
}
|
|
@@ -32819,28 +33530,28 @@ async function handler40(args, ctx) {
|
|
|
32819
33530
|
}
|
|
32820
33531
|
console.log();
|
|
32821
33532
|
console.log(
|
|
32822
|
-
" " + paint("success", "\u2713") + ` Auto-failover ${session.autoFailover ?
|
|
33533
|
+
" " + paint("success", "\u2713") + ` Auto-failover ${session.autoFailover ? chalk68.bold("on") : chalk68.bold("off")} for this session.`
|
|
32823
33534
|
);
|
|
32824
|
-
if (persist) console.log(" " +
|
|
33535
|
+
if (persist) console.log(" " + chalk68.dim("Also saved as config default."));
|
|
32825
33536
|
console.log();
|
|
32826
33537
|
return;
|
|
32827
33538
|
}
|
|
32828
33539
|
const spec = getProviderSpec(sub);
|
|
32829
33540
|
if (!spec || RESERVED.has(sub)) {
|
|
32830
33541
|
console.log();
|
|
32831
|
-
console.log(" " +
|
|
32832
|
-
console.log(" " +
|
|
32833
|
-
console.log(" " +
|
|
32834
|
-
console.log(" " +
|
|
33542
|
+
console.log(" " + chalk68.red(`Unknown engine: ${sub}`));
|
|
33543
|
+
console.log(" " + chalk68.dim("Usage: /provider [<id>|list|reset|save|failover on|off]"));
|
|
33544
|
+
console.log(" " + chalk68.dim("Connected: ") + (availableEngineLabels().join(", ") || chalk68.dim("none")));
|
|
33545
|
+
console.log(" " + chalk68.dim("Add one with ") + paint("accent", "/connect"));
|
|
32835
33546
|
console.log();
|
|
32836
33547
|
return;
|
|
32837
33548
|
}
|
|
32838
33549
|
const provider = spec.id;
|
|
32839
33550
|
if (!hasProviderKey(provider)) {
|
|
32840
33551
|
console.log();
|
|
32841
|
-
console.log(" " +
|
|
33552
|
+
console.log(" " + chalk68.red(`${spec.label} is not connected.`));
|
|
32842
33553
|
console.log(
|
|
32843
|
-
" " +
|
|
33554
|
+
" " + chalk68.dim("Type ") + paint("accent", `/connect ${provider}`) + chalk68.dim(" (or ") + paint("accent", `/config set ${spec.key_config_name}`) + chalk68.dim(").")
|
|
32844
33555
|
);
|
|
32845
33556
|
console.log();
|
|
32846
33557
|
return;
|
|
@@ -32848,11 +33559,11 @@ async function handler40(args, ctx) {
|
|
|
32848
33559
|
ensureLlmSession(ctx).provider = provider;
|
|
32849
33560
|
if (!ctx.oneShot) saveSessionState(ctx);
|
|
32850
33561
|
console.log();
|
|
32851
|
-
console.log(" " + paint("success", "\u2713") + ` Active engine: ${
|
|
32852
|
-
console.log(" " +
|
|
33562
|
+
console.log(" " + paint("success", "\u2713") + ` Active engine: ${chalk68.bold(provider)}`);
|
|
33563
|
+
console.log(" " + chalk68.dim(`Stack: ${formatActiveStack(ctx)}`));
|
|
32853
33564
|
const others = availableEngineLabels().filter((p) => p !== provider);
|
|
32854
33565
|
if (others.length > 0) {
|
|
32855
|
-
console.log(" " +
|
|
33566
|
+
console.log(" " + chalk68.dim(`Also available: ${others.join(", ")}`));
|
|
32856
33567
|
}
|
|
32857
33568
|
console.log();
|
|
32858
33569
|
}
|
|
@@ -32863,30 +33574,30 @@ function printStatus(ctx) {
|
|
|
32863
33574
|
const autoFailover = resolveAutoFailoverEnabled(ctx);
|
|
32864
33575
|
const engines = countAvailableEngines();
|
|
32865
33576
|
console.log();
|
|
32866
|
-
console.log(
|
|
33577
|
+
console.log(chalk68.bold(" LLM engines"));
|
|
32867
33578
|
console.log(` Connected: ${engines} engine${engines === 1 ? "" : "s"}`);
|
|
32868
33579
|
const configured = listProviderSpecs().filter((s) => hasProviderKey(s.id));
|
|
32869
33580
|
for (const s of configured) {
|
|
32870
33581
|
const marker2 = s.id === active ? paint("accent", " \u25BA active") : "";
|
|
32871
|
-
console.log(` ${paint("success", "\u2713")} ${s.id}${s.custom ?
|
|
33582
|
+
console.log(` ${paint("success", "\u2713")} ${s.id}${s.custom ? chalk68.dim(" (custom)") : ""}${marker2}`);
|
|
32872
33583
|
}
|
|
32873
33584
|
if (configured.length === 0) {
|
|
32874
|
-
console.log(" " +
|
|
33585
|
+
console.log(" " + chalk68.dim("none \u2014 run /connect and paste any provider key"));
|
|
32875
33586
|
}
|
|
32876
33587
|
console.log();
|
|
32877
|
-
console.log(
|
|
33588
|
+
console.log(chalk68.bold(" Active stack"));
|
|
32878
33589
|
console.log(` ${formatActiveStack(ctx)}`);
|
|
32879
33590
|
if (sessionOverride) {
|
|
32880
|
-
console.log(
|
|
33591
|
+
console.log(chalk68.dim(" (session override \u2014 /provider reset to use default)"));
|
|
32881
33592
|
} else {
|
|
32882
|
-
console.log(
|
|
33593
|
+
console.log(chalk68.dim(` (config default: ${cfg.primary})`));
|
|
32883
33594
|
}
|
|
32884
33595
|
console.log();
|
|
32885
|
-
console.log(` Auto-failover: ${autoFailover ? paint("success", "on") :
|
|
32886
|
-
console.log(
|
|
32887
|
-
console.log(
|
|
32888
|
-
console.log(
|
|
32889
|
-
console.log(
|
|
33596
|
+
console.log(` Auto-failover: ${autoFailover ? paint("success", "on") : chalk68.dim("off")}`);
|
|
33597
|
+
console.log(chalk68.dim(` /provider <id> \u2014 switch engine (${configured.map((s) => s.id).join(", ") || "none connected"})`));
|
|
33598
|
+
console.log(chalk68.dim(" /provider failover on|off \u2014 rate-limit safety net"));
|
|
33599
|
+
console.log(chalk68.dim(" /provider save \u2014 persist active engine to config"));
|
|
33600
|
+
console.log(chalk68.dim(" /connect \u2014 add another provider (any API key)"));
|
|
32890
33601
|
console.log();
|
|
32891
33602
|
}
|
|
32892
33603
|
var RESERVED;
|
|
@@ -32909,7 +33620,7 @@ var tier_exports = {};
|
|
|
32909
33620
|
__export(tier_exports, {
|
|
32910
33621
|
handler: () => handler41
|
|
32911
33622
|
});
|
|
32912
|
-
import
|
|
33623
|
+
import chalk69 from "chalk";
|
|
32913
33624
|
async function handler41(args, ctx) {
|
|
32914
33625
|
const { positional, flags } = parseArgs2(args, ["default"]);
|
|
32915
33626
|
const sub = positional[0]?.toLowerCase();
|
|
@@ -32919,8 +33630,8 @@ async function handler41(args, ctx) {
|
|
|
32919
33630
|
}
|
|
32920
33631
|
if (!TIERS.includes(sub)) {
|
|
32921
33632
|
console.log();
|
|
32922
|
-
console.log(" " +
|
|
32923
|
-
console.log(" " +
|
|
33633
|
+
console.log(" " + chalk69.red(`Unknown tier: ${sub}`));
|
|
33634
|
+
console.log(" " + chalk69.dim("Usage: /tier [high|medium|low|list] [--default]"));
|
|
32924
33635
|
console.log();
|
|
32925
33636
|
return;
|
|
32926
33637
|
}
|
|
@@ -32934,9 +33645,9 @@ async function handler41(args, ctx) {
|
|
|
32934
33645
|
}
|
|
32935
33646
|
console.log();
|
|
32936
33647
|
console.log(
|
|
32937
|
-
" " + paint("success", "\u2713") + ` Inference tier set to ${
|
|
33648
|
+
" " + paint("success", "\u2713") + ` Inference tier set to ${chalk69.bold(tier.toUpperCase())}` + (persist ? chalk69.dim(" (saved as default)") : chalk69.dim(" (this session)"))
|
|
32938
33649
|
);
|
|
32939
|
-
console.log(" " +
|
|
33650
|
+
console.log(" " + chalk69.dim(`Stack: ${formatActiveStack(ctx)}`));
|
|
32940
33651
|
console.log();
|
|
32941
33652
|
}
|
|
32942
33653
|
function printCatalog(ctx) {
|
|
@@ -32945,37 +33656,37 @@ function printCatalog(ctx) {
|
|
|
32945
33656
|
const sessionTier = ctx.llm?.tier;
|
|
32946
33657
|
const providers = getAvailableProviders();
|
|
32947
33658
|
console.log();
|
|
32948
|
-
console.log(
|
|
33659
|
+
console.log(chalk69.bold(" Inference settings"));
|
|
32949
33660
|
console.log(` Active: ${paint("accent", formatActiveStack(ctx))}`);
|
|
32950
33661
|
if (sessionTier) {
|
|
32951
|
-
console.log(
|
|
33662
|
+
console.log(chalk69.dim(" (session tier override)"));
|
|
32952
33663
|
} else {
|
|
32953
|
-
console.log(
|
|
33664
|
+
console.log(chalk69.dim(` Config default tier: ${cfg.tier.toUpperCase()}`));
|
|
32954
33665
|
}
|
|
32955
33666
|
console.log();
|
|
32956
33667
|
if (providers.length === 0) {
|
|
32957
|
-
console.log(" " +
|
|
33668
|
+
console.log(" " + chalk69.dim("No engines connected \u2014 run /connect and paste any provider key."));
|
|
32958
33669
|
console.log();
|
|
32959
33670
|
}
|
|
32960
33671
|
for (const tier of TIERS) {
|
|
32961
|
-
console.log(
|
|
33672
|
+
console.log(chalk69.bold(` ${tier.toUpperCase()}`));
|
|
32962
33673
|
for (const provider of providers) {
|
|
32963
33674
|
const modelId = resolveModelSafe(provider, tier);
|
|
32964
33675
|
if (!modelId) {
|
|
32965
|
-
console.log(` ${provider}/${
|
|
33676
|
+
console.log(` ${provider}/${chalk69.dim("no models \u2014 /model refresh")}`);
|
|
32966
33677
|
continue;
|
|
32967
33678
|
}
|
|
32968
33679
|
const isActive = provider === active.provider && tier === active.tier && modelId === active.modelId;
|
|
32969
33680
|
const marker2 = isActive ? paint("accent", "\u25BA ") : " ";
|
|
32970
33681
|
const discovered = !!getProviderModels(provider);
|
|
32971
|
-
const source = discovered ? "" :
|
|
33682
|
+
const source = discovered ? "" : chalk69.dim(" [bundled fallback]");
|
|
32972
33683
|
console.log(`${marker2}${provider}/${modelId}${source}`);
|
|
32973
33684
|
}
|
|
32974
33685
|
console.log();
|
|
32975
33686
|
}
|
|
32976
|
-
console.log(
|
|
32977
|
-
console.log(
|
|
32978
|
-
console.log(
|
|
33687
|
+
console.log(chalk69.dim(" /tier high|medium|low \u2014 set tier for this session"));
|
|
33688
|
+
console.log(chalk69.dim(" /tier high --default \u2014 also save as config default"));
|
|
33689
|
+
console.log(chalk69.dim(" /provider <id> \u2014 switch engine \xB7 /model list \u2014 browse models"));
|
|
32979
33690
|
console.log();
|
|
32980
33691
|
}
|
|
32981
33692
|
var TIERS;
|
|
@@ -32999,7 +33710,7 @@ var model_exports = {};
|
|
|
32999
33710
|
__export(model_exports, {
|
|
33000
33711
|
handler: () => handler42
|
|
33001
33712
|
});
|
|
33002
|
-
import
|
|
33713
|
+
import chalk70 from "chalk";
|
|
33003
33714
|
async function handler42(args, ctx) {
|
|
33004
33715
|
const { positional, flags } = parseArgs2(args, ["default", "all"]);
|
|
33005
33716
|
const sub = positional[0]?.toLowerCase();
|
|
@@ -33018,7 +33729,7 @@ async function handler42(args, ctx) {
|
|
|
33018
33729
|
if (!ctx.oneShot) saveSessionState(ctx);
|
|
33019
33730
|
console.log();
|
|
33020
33731
|
console.log(" " + paint("success", "\u2713") + " Model override cleared \u2014 using tier defaults.");
|
|
33021
|
-
console.log(" " +
|
|
33732
|
+
console.log(" " + chalk70.dim(`Stack: ${formatActiveStack(ctx)}`));
|
|
33022
33733
|
console.log();
|
|
33023
33734
|
return;
|
|
33024
33735
|
}
|
|
@@ -33026,7 +33737,7 @@ async function handler42(args, ctx) {
|
|
|
33026
33737
|
const modelId = positional[1];
|
|
33027
33738
|
if (!modelId) {
|
|
33028
33739
|
console.log();
|
|
33029
|
-
console.log(" " +
|
|
33740
|
+
console.log(" " + chalk70.red("Usage: /model set <model-id> [--default]"));
|
|
33030
33741
|
console.log();
|
|
33031
33742
|
return;
|
|
33032
33743
|
}
|
|
@@ -33034,7 +33745,7 @@ async function handler42(args, ctx) {
|
|
|
33034
33745
|
const providerErr = validateModelForProvider(modelId, active);
|
|
33035
33746
|
if (providerErr) {
|
|
33036
33747
|
console.log();
|
|
33037
|
-
console.log(" " +
|
|
33748
|
+
console.log(" " + chalk70.red(providerErr));
|
|
33038
33749
|
console.log();
|
|
33039
33750
|
return;
|
|
33040
33751
|
}
|
|
@@ -33043,11 +33754,11 @@ async function handler42(args, ctx) {
|
|
|
33043
33754
|
if (cache2 && !known) {
|
|
33044
33755
|
console.log();
|
|
33045
33756
|
console.log(
|
|
33046
|
-
" " +
|
|
33757
|
+
" " + chalk70.yellow("\u26A0") + ` ${modelId} isn't in ${active}'s discovered list (` + paint("accent", "/model list") + `) \u2014 saving anyway.`
|
|
33047
33758
|
);
|
|
33048
33759
|
} else if (!cache2) {
|
|
33049
33760
|
console.log();
|
|
33050
|
-
console.log(" " +
|
|
33761
|
+
console.log(" " + chalk70.yellow("\u26A0") + ` No discovered models for ${active} yet (` + paint("accent", "/model refresh") + `) \u2014 saving anyway.`);
|
|
33051
33762
|
}
|
|
33052
33763
|
const persist = getBool(flags, "default");
|
|
33053
33764
|
if (persist) {
|
|
@@ -33058,25 +33769,25 @@ async function handler42(args, ctx) {
|
|
|
33058
33769
|
}
|
|
33059
33770
|
console.log();
|
|
33060
33771
|
console.log(
|
|
33061
|
-
" " + paint("success", "\u2713") + ` Model: ${
|
|
33772
|
+
" " + paint("success", "\u2713") + ` Model: ${chalk70.bold(modelId)}` + (persist ? chalk70.dim(" (saved as default)") : chalk70.dim(" (this session)"))
|
|
33062
33773
|
);
|
|
33063
|
-
console.log(" " +
|
|
33774
|
+
console.log(" " + chalk70.dim(`Stack: ${formatActiveStack(ctx)}`));
|
|
33064
33775
|
console.log();
|
|
33065
33776
|
return;
|
|
33066
33777
|
}
|
|
33067
33778
|
const sessionOverride = ctx.llm?.modelOverride;
|
|
33068
33779
|
const globalOverride = getConfigValue("llm-model-override");
|
|
33069
33780
|
console.log();
|
|
33070
|
-
console.log(
|
|
33781
|
+
console.log(chalk70.bold(" Model"));
|
|
33071
33782
|
if (sessionOverride) {
|
|
33072
33783
|
console.log(` Session override: ${paint("accent", sessionOverride)}`);
|
|
33073
33784
|
} else if (globalOverride) {
|
|
33074
33785
|
console.log(` Config default: ${paint("accent", globalOverride)}`);
|
|
33075
33786
|
} else {
|
|
33076
|
-
console.log(" " +
|
|
33787
|
+
console.log(" " + chalk70.dim("No override \u2014 tier defaults apply."));
|
|
33077
33788
|
}
|
|
33078
33789
|
console.log(` Active stack: ${formatActiveStack(ctx)}`);
|
|
33079
|
-
console.log(
|
|
33790
|
+
console.log(chalk70.dim(" /model list \xB7 /model set <id> \xB7 /model refresh \xB7 /model clear"));
|
|
33080
33791
|
console.log();
|
|
33081
33792
|
}
|
|
33082
33793
|
function tierMarkers(cache2, modelId) {
|
|
@@ -33087,28 +33798,28 @@ function printModelList(ctx, showAll) {
|
|
|
33087
33798
|
const active = resolveActiveProvider(ctx);
|
|
33088
33799
|
const cache2 = getProviderModels(active);
|
|
33089
33800
|
console.log();
|
|
33090
|
-
console.log(
|
|
33801
|
+
console.log(chalk70.bold(` Models \u2014 ${active}`));
|
|
33091
33802
|
if (!cache2) {
|
|
33092
|
-
console.log(" " +
|
|
33093
|
-
console.log(" " +
|
|
33803
|
+
console.log(" " + chalk70.dim("Nothing discovered yet."));
|
|
33804
|
+
console.log(" " + chalk70.dim("Run ") + paint("accent", "/model refresh") + chalk70.dim(" (or ") + paint("accent", "/connect") + chalk70.dim(" to add the provider)."));
|
|
33094
33805
|
console.log();
|
|
33095
33806
|
return;
|
|
33096
33807
|
}
|
|
33097
33808
|
const fetchedAt = cache2.fetched_at.slice(0, 10);
|
|
33098
|
-
console.log(" " +
|
|
33809
|
+
console.log(" " + chalk70.dim(`${cache2.models.length} chat models \xB7 discovered ${fetchedAt} \xB7 /model refresh to update`));
|
|
33099
33810
|
console.log();
|
|
33100
33811
|
const models = showAll ? cache2.models : cache2.models.slice(0, LIST_LIMIT);
|
|
33101
33812
|
const noTools = new Set(cache2.quirks?.no_tools ?? []);
|
|
33102
33813
|
for (const m of models) {
|
|
33103
|
-
const name = m.display_name && m.display_name !== m.id ?
|
|
33104
|
-
const quirk = noTools.has(m.id) ?
|
|
33814
|
+
const name = m.display_name && m.display_name !== m.id ? chalk70.dim(` \u2014 ${m.display_name}`) : "";
|
|
33815
|
+
const quirk = noTools.has(m.id) ? chalk70.yellow(" [no tools]") : "";
|
|
33105
33816
|
console.log(` ${m.id}${name}${tierMarkers(cache2, m.id)}${quirk}`);
|
|
33106
33817
|
}
|
|
33107
33818
|
if (!showAll && cache2.models.length > models.length) {
|
|
33108
|
-
console.log(" " +
|
|
33819
|
+
console.log(" " + chalk70.dim(`\u2026 and ${cache2.models.length - models.length} more (/model list --all)`));
|
|
33109
33820
|
}
|
|
33110
33821
|
console.log();
|
|
33111
|
-
console.log(" " +
|
|
33822
|
+
console.log(" " + chalk70.dim("/model set <id> \u2014 pin one for this session (--default to persist)"));
|
|
33112
33823
|
console.log();
|
|
33113
33824
|
}
|
|
33114
33825
|
async function refreshModels(ctx) {
|
|
@@ -33117,13 +33828,13 @@ async function refreshModels(ctx) {
|
|
|
33117
33828
|
const entry = await refreshProviderModels(active, { force: true });
|
|
33118
33829
|
if (!entry) {
|
|
33119
33830
|
spinner.fail(`Couldn't reach ${active} to refresh models.`);
|
|
33120
|
-
console.log(" " +
|
|
33831
|
+
console.log(" " + chalk70.dim("Check your connection and key, then retry. Cached models remain in use."));
|
|
33121
33832
|
console.log();
|
|
33122
33833
|
return;
|
|
33123
33834
|
}
|
|
33124
33835
|
spinner.succeed(`${active}: ${entry.models.length} chat models discovered.`);
|
|
33125
|
-
console.log(" " +
|
|
33126
|
-
console.log(" " +
|
|
33836
|
+
console.log(" " + chalk70.dim(`high ${entry.tier_stack.high} \xB7 medium ${entry.tier_stack.medium} \xB7 low ${entry.tier_stack.low}`));
|
|
33837
|
+
console.log(" " + chalk70.dim(`Stack: ${formatActiveStack(ctx)}`));
|
|
33127
33838
|
console.log();
|
|
33128
33839
|
}
|
|
33129
33840
|
var LIST_LIMIT;
|
|
@@ -33143,27 +33854,20 @@ var init_model = __esm({
|
|
|
33143
33854
|
});
|
|
33144
33855
|
|
|
33145
33856
|
// src/config/update-check.ts
|
|
33146
|
-
|
|
33147
|
-
__export(update_check_exports, {
|
|
33148
|
-
invalidateUpdateCheckCache: () => invalidateUpdateCheckCache,
|
|
33149
|
-
isCacheFresh: () => isCacheFresh,
|
|
33150
|
-
loadUpdateCheckCache: () => loadUpdateCheckCache,
|
|
33151
|
-
saveUpdateCheckCache: () => saveUpdateCheckCache
|
|
33152
|
-
});
|
|
33153
|
-
import { existsSync as existsSync28, mkdirSync as mkdirSync18, readFileSync as readFileSync21, unlinkSync as unlinkSync5, writeFileSync as writeFileSync20 } from "fs";
|
|
33857
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync18, readFileSync as readFileSync21, unlinkSync as unlinkSync5, writeFileSync as writeFileSync20 } from "fs";
|
|
33154
33858
|
import { join as join33 } from "path";
|
|
33155
33859
|
function cachePath2() {
|
|
33156
33860
|
return join33(ntrpHome(), "update-check.json");
|
|
33157
33861
|
}
|
|
33158
33862
|
function ensureDir7() {
|
|
33159
33863
|
const dir = ntrpHome();
|
|
33160
|
-
if (!
|
|
33864
|
+
if (!existsSync29(dir)) {
|
|
33161
33865
|
mkdirSync18(dir, { recursive: true });
|
|
33162
33866
|
}
|
|
33163
33867
|
}
|
|
33164
33868
|
function loadUpdateCheckCache() {
|
|
33165
33869
|
const path = cachePath2();
|
|
33166
|
-
if (!
|
|
33870
|
+
if (!existsSync29(path)) return null;
|
|
33167
33871
|
try {
|
|
33168
33872
|
const parsed = JSON.parse(readFileSync21(path, "utf-8"));
|
|
33169
33873
|
if (!parsed || typeof parsed !== "object" || typeof parsed.lastCheck !== "number" || typeof parsed.latestVersion !== "string") {
|
|
@@ -33184,7 +33888,7 @@ function isCacheFresh(cache2, ttlMs = CACHE_TTL_MS2) {
|
|
|
33184
33888
|
}
|
|
33185
33889
|
function invalidateUpdateCheckCache() {
|
|
33186
33890
|
const path = cachePath2();
|
|
33187
|
-
if (
|
|
33891
|
+
if (existsSync29(path)) {
|
|
33188
33892
|
unlinkSync5(path);
|
|
33189
33893
|
}
|
|
33190
33894
|
}
|
|
@@ -33198,7 +33902,7 @@ var init_update_check = __esm({
|
|
|
33198
33902
|
});
|
|
33199
33903
|
|
|
33200
33904
|
// src/version.ts
|
|
33201
|
-
import { existsSync as
|
|
33905
|
+
import { existsSync as existsSync30, readFileSync as readFileSync22 } from "fs";
|
|
33202
33906
|
import { dirname as dirname6, join as join34 } from "path";
|
|
33203
33907
|
import { fileURLToPath } from "url";
|
|
33204
33908
|
function getInstalledVersion() {
|
|
@@ -33206,7 +33910,7 @@ function getInstalledVersion() {
|
|
|
33206
33910
|
const start = dirname6(fileURLToPath(import.meta.url));
|
|
33207
33911
|
for (const rel of ["../package.json", "../../package.json"]) {
|
|
33208
33912
|
const path = join34(start, rel);
|
|
33209
|
-
if (!
|
|
33913
|
+
if (!existsSync30(path)) continue;
|
|
33210
33914
|
try {
|
|
33211
33915
|
const pkg = JSON.parse(readFileSync22(path, "utf-8"));
|
|
33212
33916
|
if (typeof pkg.version === "string" && pkg.version.length > 0) {
|
|
@@ -33230,10 +33934,13 @@ var init_version = __esm({
|
|
|
33230
33934
|
var registry_exports = {};
|
|
33231
33935
|
__export(registry_exports, {
|
|
33232
33936
|
NPM_PACKAGE: () => NPM_PACKAGE,
|
|
33937
|
+
applyUpdateCheckResult: () => applyUpdateCheckResult,
|
|
33233
33938
|
checkForUpdate: () => checkForUpdate,
|
|
33234
33939
|
fetchLatestVersion: () => fetchLatestVersion,
|
|
33235
33940
|
formatUpdateNudge: () => formatUpdateNudge,
|
|
33236
|
-
|
|
33941
|
+
hydrateUpdateAvailableFromCache: () => hydrateUpdateAvailableFromCache,
|
|
33942
|
+
isNewerVersion: () => isNewerVersion,
|
|
33943
|
+
startBackgroundUpdateCheck: () => startBackgroundUpdateCheck
|
|
33237
33944
|
});
|
|
33238
33945
|
function registryUrl() {
|
|
33239
33946
|
return process.env.NTRP_REGISTRY_URL ?? "https://registry.npmjs.org/@sonnechasser/ntrp/latest";
|
|
@@ -33252,7 +33959,27 @@ function isNewerVersion(latest, current) {
|
|
|
33252
33959
|
return lPatch > cPatch;
|
|
33253
33960
|
}
|
|
33254
33961
|
function formatUpdateNudge(current, latest) {
|
|
33255
|
-
return `\u26A1 NTRP v${latest} available (
|
|
33962
|
+
return `\u26A1 NTRP v${latest} available (running v${current}) \u2014 type /update`;
|
|
33963
|
+
}
|
|
33964
|
+
function hydrateUpdateAvailableFromCache(current) {
|
|
33965
|
+
const cached2 = loadUpdateCheckCache();
|
|
33966
|
+
if (!cached2?.latestVersion) return void 0;
|
|
33967
|
+
if (!isNewerVersion(cached2.latestVersion, current)) return void 0;
|
|
33968
|
+
return { current, latest: cached2.latestVersion };
|
|
33969
|
+
}
|
|
33970
|
+
function applyUpdateCheckResult(ctx, result) {
|
|
33971
|
+
if (result?.updateAvailable) {
|
|
33972
|
+
ctx.updateAvailable = { current: result.current, latest: result.latest };
|
|
33973
|
+
return;
|
|
33974
|
+
}
|
|
33975
|
+
if (result && !result.updateAvailable) {
|
|
33976
|
+
ctx.updateAvailable = void 0;
|
|
33977
|
+
}
|
|
33978
|
+
}
|
|
33979
|
+
function startBackgroundUpdateCheck(ctx) {
|
|
33980
|
+
const pending = checkForUpdate({ force: true, timeoutMs: 5e3 });
|
|
33981
|
+
ctx.pendingUpdateCheck = pending;
|
|
33982
|
+
void pending.then((result) => applyUpdateCheckResult(ctx, result)).catch(() => void 0);
|
|
33256
33983
|
}
|
|
33257
33984
|
async function fetchLatestVersion(timeoutMs = 5e3) {
|
|
33258
33985
|
try {
|
|
@@ -33299,18 +34026,83 @@ var init_registry = __esm({
|
|
|
33299
34026
|
}
|
|
33300
34027
|
});
|
|
33301
34028
|
|
|
34029
|
+
// src/update/relaunch.ts
|
|
34030
|
+
var relaunch_exports = {};
|
|
34031
|
+
__export(relaunch_exports, {
|
|
34032
|
+
JUST_UPDATED_ENV: () => JUST_UPDATED_ENV,
|
|
34033
|
+
consumeJustUpdatedEnv: () => consumeJustUpdatedEnv,
|
|
34034
|
+
encodeJustUpdated: () => encodeJustUpdated,
|
|
34035
|
+
relaunchIntoHome: () => relaunchIntoHome,
|
|
34036
|
+
updateRestartSummary: () => updateRestartSummary
|
|
34037
|
+
});
|
|
34038
|
+
import { spawnSync } from "child_process";
|
|
34039
|
+
function encodeJustUpdated(fromVersion, toVersion) {
|
|
34040
|
+
return `${fromVersion}\u2192${toVersion}`;
|
|
34041
|
+
}
|
|
34042
|
+
function consumeJustUpdatedEnv() {
|
|
34043
|
+
const raw = process.env[JUST_UPDATED_ENV];
|
|
34044
|
+
if (!raw) return null;
|
|
34045
|
+
delete process.env[JUST_UPDATED_ENV];
|
|
34046
|
+
const sep5 = raw.includes("\u2192") ? "\u2192" : "->";
|
|
34047
|
+
const idx = raw.indexOf(sep5);
|
|
34048
|
+
if (idx <= 0) return null;
|
|
34049
|
+
const from = raw.slice(0, idx);
|
|
34050
|
+
const to = raw.slice(idx + sep5.length);
|
|
34051
|
+
if (!from || !to) return null;
|
|
34052
|
+
return { from, to };
|
|
34053
|
+
}
|
|
34054
|
+
function updateRestartSummary(toVersion) {
|
|
34055
|
+
return `Restart NTRP to use v${toVersion}`;
|
|
34056
|
+
}
|
|
34057
|
+
async function relaunchIntoHome(opts) {
|
|
34058
|
+
const { stopSessionTranscript: stopSessionTranscript2 } = await Promise.resolve().then(() => (init_transcript(), transcript_exports));
|
|
34059
|
+
const { close: close2 } = await Promise.resolve().then(() => (init_connection(), connection_exports));
|
|
34060
|
+
stopSessionTranscript2();
|
|
34061
|
+
await close2();
|
|
34062
|
+
try {
|
|
34063
|
+
opts.rl?.pause();
|
|
34064
|
+
} catch {
|
|
34065
|
+
}
|
|
34066
|
+
const result = spawnSync(process.execPath, process.argv.slice(1), {
|
|
34067
|
+
stdio: "inherit",
|
|
34068
|
+
env: {
|
|
34069
|
+
...process.env,
|
|
34070
|
+
[JUST_UPDATED_ENV]: encodeJustUpdated(opts.fromVersion, opts.toVersion)
|
|
34071
|
+
}
|
|
34072
|
+
});
|
|
34073
|
+
if (result.error) {
|
|
34074
|
+
try {
|
|
34075
|
+
opts.rl?.resume();
|
|
34076
|
+
} catch {
|
|
34077
|
+
}
|
|
34078
|
+
return "failed";
|
|
34079
|
+
}
|
|
34080
|
+
process.exit(result.status ?? 0);
|
|
34081
|
+
return "failed";
|
|
34082
|
+
}
|
|
34083
|
+
var JUST_UPDATED_ENV;
|
|
34084
|
+
var init_relaunch = __esm({
|
|
34085
|
+
"src/update/relaunch.ts"() {
|
|
34086
|
+
"use strict";
|
|
34087
|
+
JUST_UPDATED_ENV = "NTRP_JUST_UPDATED";
|
|
34088
|
+
}
|
|
34089
|
+
});
|
|
34090
|
+
|
|
33302
34091
|
// src/commands/update.ts
|
|
33303
34092
|
var update_exports = {};
|
|
33304
34093
|
__export(update_exports, {
|
|
33305
34094
|
handler: () => handler43
|
|
33306
34095
|
});
|
|
33307
|
-
import { spawnSync } from "child_process";
|
|
33308
|
-
import
|
|
34096
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
34097
|
+
import chalk71 from "chalk";
|
|
33309
34098
|
function tailLines(text, count = 5) {
|
|
33310
34099
|
return text.split("\n").map((line) => line.trimEnd()).filter((line) => line.length > 0).slice(-count).join("\n");
|
|
33311
34100
|
}
|
|
33312
34101
|
function runGlobalInstall() {
|
|
33313
|
-
|
|
34102
|
+
if (process.env.NTRP_UPDATE_NPM_STUB === "1") {
|
|
34103
|
+
return { ok: true, output: "stub" };
|
|
34104
|
+
}
|
|
34105
|
+
const result = spawnSync2(
|
|
33314
34106
|
"npm",
|
|
33315
34107
|
["install", "-g", `${NPM_PACKAGE}@latest`],
|
|
33316
34108
|
{
|
|
@@ -33321,19 +34113,19 @@ function runGlobalInstall() {
|
|
|
33321
34113
|
const output = [result.stdout, result.stderr].filter(Boolean).join("\n");
|
|
33322
34114
|
return { ok: result.status === 0, output };
|
|
33323
34115
|
}
|
|
33324
|
-
async function handler43(_args,
|
|
34116
|
+
async function handler43(_args, ctx) {
|
|
33325
34117
|
const current = getInstalledVersion();
|
|
33326
34118
|
const latest = await fetchLatestVersion(1e4);
|
|
33327
34119
|
if (!latest) {
|
|
33328
34120
|
console.log();
|
|
33329
|
-
console.log(
|
|
33330
|
-
console.log(
|
|
34121
|
+
console.log(chalk71.yellow(" Could not reach the npm registry."));
|
|
34122
|
+
console.log(chalk71.dim(` Try manually: npm install -g ${NPM_PACKAGE}`));
|
|
33331
34123
|
console.log();
|
|
33332
34124
|
return;
|
|
33333
34125
|
}
|
|
33334
34126
|
if (!isNewerVersion(latest, current)) {
|
|
33335
34127
|
console.log();
|
|
33336
|
-
console.log(
|
|
34128
|
+
console.log(chalk71.green(` \u2713 You are on the latest version (v${current})`));
|
|
33337
34129
|
console.log();
|
|
33338
34130
|
return;
|
|
33339
34131
|
}
|
|
@@ -33342,24 +34134,39 @@ async function handler43(_args, _ctx) {
|
|
|
33342
34134
|
const { ok, output } = runGlobalInstall();
|
|
33343
34135
|
if (ok) {
|
|
33344
34136
|
invalidateUpdateCheckCache();
|
|
33345
|
-
|
|
34137
|
+
if (ctx.oneShot) {
|
|
34138
|
+
console.log(chalk71.green(` \u2713 Updated! ${updateRestartSummary(latest)}`));
|
|
34139
|
+
console.log();
|
|
34140
|
+
return;
|
|
34141
|
+
}
|
|
33346
34142
|
console.log();
|
|
34143
|
+
const failed = await relaunchIntoHome({
|
|
34144
|
+
fromVersion: current,
|
|
34145
|
+
toVersion: latest,
|
|
34146
|
+
rl: ctx.rl
|
|
34147
|
+
});
|
|
34148
|
+
if (failed) {
|
|
34149
|
+
const restart = updateRestartSummary(latest);
|
|
34150
|
+
console.log(chalk71.green(` \u2713 Updated! ${restart}`));
|
|
34151
|
+
console.log();
|
|
34152
|
+
return restart;
|
|
34153
|
+
}
|
|
33347
34154
|
return;
|
|
33348
34155
|
}
|
|
33349
34156
|
const lower = output.toLowerCase();
|
|
33350
34157
|
if (lower.includes("eacces") || lower.includes("permission denied") || lower.includes("eperm")) {
|
|
33351
|
-
console.log(
|
|
33352
|
-
console.log(
|
|
33353
|
-
console.log(
|
|
34158
|
+
console.log(chalk71.red(` Could not install ${NPM_PACKAGE} (permission denied).`));
|
|
34159
|
+
console.log(chalk71.dim(` Try: sudo npm install -g ${NPM_PACKAGE}`));
|
|
34160
|
+
console.log(chalk71.dim(` Or fix npm global permissions: ${PERMISSIONS_URL}`));
|
|
33354
34161
|
console.log();
|
|
33355
34162
|
return;
|
|
33356
34163
|
}
|
|
33357
34164
|
const detail = tailLines(output);
|
|
33358
|
-
console.log(
|
|
34165
|
+
console.log(chalk71.red(` Could not install ${NPM_PACKAGE}.`));
|
|
33359
34166
|
if (detail) {
|
|
33360
|
-
console.log(
|
|
34167
|
+
console.log(chalk71.dim(` ${detail.split("\n").join("\n ")}`));
|
|
33361
34168
|
}
|
|
33362
|
-
console.log(
|
|
34169
|
+
console.log(chalk71.dim(` Try manually: npm install -g ${NPM_PACKAGE}`));
|
|
33363
34170
|
console.log();
|
|
33364
34171
|
}
|
|
33365
34172
|
var PERMISSIONS_URL;
|
|
@@ -33368,16 +34175,17 @@ var init_update = __esm({
|
|
|
33368
34175
|
"use strict";
|
|
33369
34176
|
init_update_check();
|
|
33370
34177
|
init_registry();
|
|
34178
|
+
init_relaunch();
|
|
33371
34179
|
init_version();
|
|
33372
34180
|
PERMISSIONS_URL = "https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally";
|
|
33373
34181
|
}
|
|
33374
34182
|
});
|
|
33375
34183
|
|
|
33376
34184
|
// src/output/progress-report.ts
|
|
33377
|
-
import
|
|
34185
|
+
import chalk72 from "chalk";
|
|
33378
34186
|
function printCard(title, rows) {
|
|
33379
34187
|
const inner = CARD_W - 4;
|
|
33380
|
-
const border =
|
|
34188
|
+
const border = chalk72.dim;
|
|
33381
34189
|
console.log();
|
|
33382
34190
|
console.log(` ${border(`\u256D${"\u2500".repeat(CARD_W - 2)}\u256E`)}`);
|
|
33383
34191
|
console.log(` ${border("\u2502 ")}${padRight(sectionHeading(title), inner)}${border(" \u2502")}`);
|
|
@@ -33393,7 +34201,7 @@ function formatTokens(n) {
|
|
|
33393
34201
|
return String(n);
|
|
33394
34202
|
}
|
|
33395
34203
|
function sparkline(values) {
|
|
33396
|
-
if (values.length === 0) return
|
|
34204
|
+
if (values.length === 0) return chalk72.dim("(no activity yet)");
|
|
33397
34205
|
const max = Math.max(...values, 1);
|
|
33398
34206
|
const blocks = ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
|
|
33399
34207
|
return values.map((v) => {
|
|
@@ -33402,7 +34210,7 @@ function sparkline(values) {
|
|
|
33402
34210
|
}).join("");
|
|
33403
34211
|
}
|
|
33404
34212
|
function formatMemberSince(iso) {
|
|
33405
|
-
if (!iso) return
|
|
34213
|
+
if (!iso) return chalk72.dim("\u2014");
|
|
33406
34214
|
const d = new Date(iso);
|
|
33407
34215
|
return d.toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
|
|
33408
34216
|
}
|
|
@@ -33424,25 +34232,25 @@ function renderProgressReport() {
|
|
|
33424
34232
|
const nextLabel = bank.next_milestone ? `${formatHoursLabel(bank.total_hours)} \u2192 ${formatHoursLabel(bank.next_milestone.hours)}` : `${formatHoursLabel(bank.total_hours)} saved`;
|
|
33425
34233
|
const bar = inlineBar(bank.progress_pct, 18);
|
|
33426
34234
|
printCard("Progress", [
|
|
33427
|
-
`${
|
|
33428
|
-
`${
|
|
33429
|
-
`${
|
|
33430
|
-
`${
|
|
34235
|
+
`${chalk72.dim("Hours saved")} ${paint("accent", formatHoursLabel(bank.total_hours))} ${bar}`,
|
|
34236
|
+
`${chalk72.dim("Next milestone")} ${bank.next_milestone ? paint("accent", bank.next_milestone.title) : chalk72.dim("all complete")}`,
|
|
34237
|
+
`${chalk72.dim("Member since")} ${formatMemberSince(usage4.first_active_at)}`,
|
|
34238
|
+
`${chalk72.dim("Last active")} ${formatMemberSince(usage4.last_active_at)}`
|
|
33431
34239
|
]);
|
|
33432
34240
|
if (bank.perspective_line) {
|
|
33433
|
-
console.log(` ${
|
|
34241
|
+
console.log(` ${chalk72.dim(bank.perspective_line)}`);
|
|
33434
34242
|
}
|
|
33435
34243
|
printCard("Activity", [
|
|
33436
|
-
`${
|
|
33437
|
-
`${
|
|
33438
|
-
`${
|
|
33439
|
-
`${
|
|
33440
|
-
`${
|
|
34244
|
+
`${chalk72.dim("Sessions")} ${chalk72.bold(String(summary.total_sessions_on_disk))} total \xB7 ${summary.sessions_with_work} with analysis \xB7 ${usage4.sessions_closed} closed`,
|
|
34245
|
+
`${chalk72.dim("Diagnoses")} ${chalk72.bold(String(usage4.diagnoses))}`,
|
|
34246
|
+
`${chalk72.dim("Metrics runs")} ${chalk72.bold(String(usage4.metrics_runs))}`,
|
|
34247
|
+
`${chalk72.dim("Deliverables")} ${chalk72.bold(String(usage4.deliverables))}`,
|
|
34248
|
+
`${chalk72.dim("AI exchanges")} ${chalk72.bold(String(usage4.nl_exchanges))}`
|
|
33441
34249
|
]);
|
|
33442
34250
|
const totalTokens = usage4.input_tokens + usage4.output_tokens;
|
|
33443
34251
|
printCard("AI usage", [
|
|
33444
|
-
`${
|
|
33445
|
-
`${
|
|
34252
|
+
`${chalk72.dim("LLM calls")} ${chalk72.bold(String(usage4.llm_calls))}`,
|
|
34253
|
+
`${chalk72.dim("Tokens")} ${chalk72.bold(formatTokens(totalTokens))} in+out (${formatTokens(usage4.input_tokens)} in \xB7 ${formatTokens(usage4.output_tokens)} out)`
|
|
33446
34254
|
]);
|
|
33447
34255
|
const weeks = [...usage4.weekly].sort((a, b) => a.week.localeCompare(b.week)).slice(-8);
|
|
33448
34256
|
const weekHours = weeks.map((w) => w.minutes_saved / 60);
|
|
@@ -33451,25 +34259,25 @@ function renderProgressReport() {
|
|
|
33451
34259
|
console.log(` ${sectionHeading("Weekly hours saved")}`);
|
|
33452
34260
|
console.log(` ${sparkline(weekHours)}`);
|
|
33453
34261
|
if (weeks.length > 0) {
|
|
33454
|
-
console.log(` ${
|
|
34262
|
+
console.log(` ${chalk72.dim(weekLabels.join(" "))}`);
|
|
33455
34263
|
}
|
|
33456
34264
|
console.log();
|
|
33457
34265
|
console.log(` ${sectionHeading("Onboarding")}`);
|
|
33458
34266
|
for (const m of ACTIVITY_MILESTONES) {
|
|
33459
34267
|
const unlocked = state2.milestones_unlocked.includes(m.id);
|
|
33460
|
-
const mark = unlocked ? badge("DONE", "success") :
|
|
33461
|
-
console.log(` ${mark} ${
|
|
34268
|
+
const mark = unlocked ? badge("DONE", "success") : chalk72.dim("\u25CB");
|
|
34269
|
+
console.log(` ${mark} ${chalk72.dim(m.title.padEnd(16))} ${unlocked ? chalk72.dim(m.message) : chalk72.dim("Type /deepdive")}`);
|
|
33462
34270
|
}
|
|
33463
34271
|
console.log();
|
|
33464
34272
|
console.log(` ${sectionHeading("Milestones")}`);
|
|
33465
34273
|
for (const m of TIME_MILESTONES) {
|
|
33466
34274
|
const unlocked = state2.milestones_unlocked.includes(m.id);
|
|
33467
34275
|
const pct = Math.min(100, bank.total_hours / m.hours * 100);
|
|
33468
|
-
const mark = unlocked ? badge("DONE", "success") : bank.total_hours >= m.hours * 0.85 ? badge("NEAR", "warning") :
|
|
34276
|
+
const mark = unlocked ? badge("DONE", "success") : bank.total_hours >= m.hours * 0.85 ? badge("NEAR", "warning") : chalk72.dim("\u25CB");
|
|
33469
34277
|
const barW = 12;
|
|
33470
|
-
const mBar = unlocked ?
|
|
34278
|
+
const mBar = unlocked ? chalk72.hex("#22c55e")("\u2588".repeat(barW)) : scoreBar(pct, bank.total_hours >= m.hours ? "green" : pct >= 50 ? "yellow" : "red", barW);
|
|
33471
34279
|
const label = `${m.title}`.padEnd(16);
|
|
33472
|
-
console.log(` ${mark} ${
|
|
34280
|
+
console.log(` ${mark} ${chalk72.dim(label)} ${mBar} ${chalk72.dim(`${m.hours}h`)}`);
|
|
33473
34281
|
}
|
|
33474
34282
|
console.log();
|
|
33475
34283
|
}
|
|
@@ -33493,15 +34301,15 @@ var progress_exports = {};
|
|
|
33493
34301
|
__export(progress_exports, {
|
|
33494
34302
|
handler: () => handler44
|
|
33495
34303
|
});
|
|
33496
|
-
import
|
|
34304
|
+
import chalk73 from "chalk";
|
|
33497
34305
|
function printProgressResetPreamble() {
|
|
33498
34306
|
console.log();
|
|
33499
|
-
console.log(" " +
|
|
33500
|
-
console.log(" " +
|
|
33501
|
-
console.log(" " +
|
|
33502
|
-
console.log(" " +
|
|
34307
|
+
console.log(" " + chalk73.yellow.bold("This will permanently remove:"));
|
|
34308
|
+
console.log(" " + chalk73.dim(" \u2022 Hours saved and milestone unlocks"));
|
|
34309
|
+
console.log(" " + chalk73.dim(" \u2022 Usage counters and weekly activity totals"));
|
|
34310
|
+
console.log(" " + chalk73.dim(" \u2022 Credit history used to prevent duplicates"));
|
|
33503
34311
|
console.log();
|
|
33504
|
-
console.log(" " +
|
|
34312
|
+
console.log(" " + chalk73.dim("Kept: install identity (install.json)"));
|
|
33505
34313
|
console.log();
|
|
33506
34314
|
}
|
|
33507
34315
|
function showProgress() {
|
|
@@ -33519,7 +34327,7 @@ async function handleReset(ctx, confirmedFlag) {
|
|
|
33519
34327
|
const bank = getTimeBankSummary();
|
|
33520
34328
|
if (bank.total_minutes <= 0) {
|
|
33521
34329
|
console.log();
|
|
33522
|
-
console.log(" " +
|
|
34330
|
+
console.log(" " + chalk73.dim("No progress to reset."));
|
|
33523
34331
|
console.log();
|
|
33524
34332
|
return "No progress to reset";
|
|
33525
34333
|
}
|
|
@@ -33536,7 +34344,7 @@ async function handleReset(ctx, confirmedFlag) {
|
|
|
33536
34344
|
}
|
|
33537
34345
|
resetProgress();
|
|
33538
34346
|
console.log();
|
|
33539
|
-
console.log(" " + paint("accent", "\u2713 Progress reset") +
|
|
34347
|
+
console.log(" " + paint("accent", "\u2713 Progress reset") + chalk73.dim(" \u2014 hours and milestones are cleared."));
|
|
33540
34348
|
console.log();
|
|
33541
34349
|
return "Progress reset";
|
|
33542
34350
|
}
|
|
@@ -33548,7 +34356,7 @@ async function handler44(args, ctx) {
|
|
|
33548
34356
|
}
|
|
33549
34357
|
if (sub && sub !== "reset") {
|
|
33550
34358
|
console.log();
|
|
33551
|
-
console.log(" " +
|
|
34359
|
+
console.log(" " + chalk73.dim("Unknown subcommand. Type ") + paint("accent", "/progress") + chalk73.dim(" or ") + paint("accent", "/progress reset") + chalk73.dim("."));
|
|
33552
34360
|
console.log();
|
|
33553
34361
|
return;
|
|
33554
34362
|
}
|
|
@@ -33571,7 +34379,7 @@ var deepdive_exports = {};
|
|
|
33571
34379
|
__export(deepdive_exports, {
|
|
33572
34380
|
handler: () => handler45
|
|
33573
34381
|
});
|
|
33574
|
-
import
|
|
34382
|
+
import chalk74 from "chalk";
|
|
33575
34383
|
function printCatalog2() {
|
|
33576
34384
|
console.log();
|
|
33577
34385
|
console.log(" " + sectionHeading("Vital signs"));
|
|
@@ -33581,7 +34389,7 @@ function printCatalog2() {
|
|
|
33581
34389
|
console.log();
|
|
33582
34390
|
console.log(" " + sectionHeading("SaaS metrics"));
|
|
33583
34391
|
console.log(
|
|
33584
|
-
" " +
|
|
34392
|
+
" " + chalk74.dim("Core tour: ") + CORE_DECK_IDS.filter((id) => getMetricExplainer(id)?.kind === "saas").map((id) => paint("accent", id)).join(chalk74.dim(" \xB7 "))
|
|
33585
34393
|
);
|
|
33586
34394
|
console.log();
|
|
33587
34395
|
for (const e of listMetricExplainers("saas")) {
|
|
@@ -33590,7 +34398,7 @@ function printCatalog2() {
|
|
|
33590
34398
|
console.log();
|
|
33591
34399
|
console.log(" " + sectionHeading("How to use NTRP"));
|
|
33592
34400
|
console.log(
|
|
33593
|
-
" " +
|
|
34401
|
+
" " + chalk74.dim("After vitals in the tour: ") + GUIDE_DECK_IDS.map((id) => paint("accent", id)).join(chalk74.dim(" \xB7 ")) + chalk74.dim(" \xB7 ") + paint("accent", "/deepdive guide")
|
|
33594
34402
|
);
|
|
33595
34403
|
console.log();
|
|
33596
34404
|
for (const s of listGuideSlides()) {
|
|
@@ -33598,14 +34406,14 @@ function printCatalog2() {
|
|
|
33598
34406
|
}
|
|
33599
34407
|
console.log();
|
|
33600
34408
|
console.log(
|
|
33601
|
-
" " +
|
|
34409
|
+
" " + chalk74.dim("Usage: ") + paint("accent", "/deepdive") + chalk74.dim(" \xB7 ") + paint("accent", "/deepdive <metric>") + chalk74.dim(" \xB7 ") + paint("accent", "/deepdive guide") + chalk74.dim(" \xB7 ") + paint("accent", "/deepdive list")
|
|
33602
34410
|
);
|
|
33603
34411
|
console.log();
|
|
33604
34412
|
}
|
|
33605
34413
|
function printUnknown(query) {
|
|
33606
34414
|
console.log();
|
|
33607
34415
|
console.log(
|
|
33608
|
-
" " +
|
|
34416
|
+
" " + chalk74.dim("Unknown slide ") + bold(query) + chalk74.dim(" \u2014 try ") + paint("accent", "/deepdive list") + chalk74.dim(" or ") + paint("accent", "/deepdive guide") + chalk74.dim(".")
|
|
33609
34417
|
);
|
|
33610
34418
|
console.log();
|
|
33611
34419
|
}
|
|
@@ -33674,22 +34482,90 @@ var init_deepdive = __esm({
|
|
|
33674
34482
|
}
|
|
33675
34483
|
});
|
|
33676
34484
|
|
|
34485
|
+
// src/commands/thinkwithme.ts
|
|
34486
|
+
var thinkwithme_exports = {};
|
|
34487
|
+
__export(thinkwithme_exports, {
|
|
34488
|
+
handler: () => handler46
|
|
34489
|
+
});
|
|
34490
|
+
import chalk75 from "chalk";
|
|
34491
|
+
async function handler46(args, ctx) {
|
|
34492
|
+
const seedRaw = args.join(" ").trim();
|
|
34493
|
+
const seed = seedRaw ? extractThinkSeed(seedRaw) : void 0;
|
|
34494
|
+
if (ctx.oneShot) {
|
|
34495
|
+
await runOneShot(ctx, seed);
|
|
34496
|
+
return;
|
|
34497
|
+
}
|
|
34498
|
+
await startThinkFlow(ctx, { seed, origin: "command" });
|
|
34499
|
+
}
|
|
34500
|
+
async function runOneShot(ctx, seed) {
|
|
34501
|
+
if (!seed) {
|
|
34502
|
+
console.log();
|
|
34503
|
+
console.log(
|
|
34504
|
+
" " + chalk75.dim("Usage: ") + paint("accent", "ntrp thinkwithme <topic>") + chalk75.dim(" \u2014 or open the REPL and type ") + chalk75.cyan("/thinkwithme") + chalk75.dim(".")
|
|
34505
|
+
);
|
|
34506
|
+
console.log();
|
|
34507
|
+
return;
|
|
34508
|
+
}
|
|
34509
|
+
if (!isAnalysisReady(ctx)) {
|
|
34510
|
+
console.log();
|
|
34511
|
+
console.log(
|
|
34512
|
+
" " + chalk75.dim("No analysis yet. Run ") + chalk75.cyan("ntrp demo --scenario hidden_crisis --no-profile") + chalk75.dim(" then ") + chalk75.cyan("ntrp diagnose") + chalk75.dim(", or use the interactive REPL.")
|
|
34513
|
+
);
|
|
34514
|
+
console.log();
|
|
34515
|
+
process.exitCode = 1;
|
|
34516
|
+
return;
|
|
34517
|
+
}
|
|
34518
|
+
if (!canUseReplAi(ctx)) {
|
|
34519
|
+
console.log();
|
|
34520
|
+
console.log(
|
|
34521
|
+
" " + chalk75.dim("Connect an AI key first: ") + chalk75.cyan("ntrp connect --key <key>")
|
|
34522
|
+
);
|
|
34523
|
+
console.log();
|
|
34524
|
+
process.exitCode = 1;
|
|
34525
|
+
return;
|
|
34526
|
+
}
|
|
34527
|
+
ctx.thinkState = {
|
|
34528
|
+
step: "active",
|
|
34529
|
+
seed,
|
|
34530
|
+
origin: "command",
|
|
34531
|
+
started_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34532
|
+
open_questions: [],
|
|
34533
|
+
challenged_assumptions: [],
|
|
34534
|
+
working_hypotheses: []
|
|
34535
|
+
};
|
|
34536
|
+
console.log();
|
|
34537
|
+
console.log(" " + paint("accent", "Think with me"));
|
|
34538
|
+
console.log(" " + chalk75.dim("Seed: ") + seed);
|
|
34539
|
+
console.log();
|
|
34540
|
+
const { runThinkTurn: runThinkTurn2 } = await Promise.resolve().then(() => (init_think(), think_exports));
|
|
34541
|
+
await runThinkTurn2(seed, ctx);
|
|
34542
|
+
}
|
|
34543
|
+
var init_thinkwithme = __esm({
|
|
34544
|
+
"src/commands/thinkwithme.ts"() {
|
|
34545
|
+
"use strict";
|
|
34546
|
+
init_context2();
|
|
34547
|
+
init_repl_api();
|
|
34548
|
+
init_theme();
|
|
34549
|
+
init_think_flow();
|
|
34550
|
+
}
|
|
34551
|
+
});
|
|
34552
|
+
|
|
33677
34553
|
// src/commands/exports.ts
|
|
33678
34554
|
var exports_exports = {};
|
|
33679
34555
|
__export(exports_exports, {
|
|
33680
|
-
handler: () =>
|
|
34556
|
+
handler: () => handler47
|
|
33681
34557
|
});
|
|
33682
|
-
import
|
|
33683
|
-
import { existsSync as
|
|
34558
|
+
import chalk76 from "chalk";
|
|
34559
|
+
import { existsSync as existsSync31 } from "fs";
|
|
33684
34560
|
import { join as join35 } from "path";
|
|
33685
34561
|
function usage3() {
|
|
33686
|
-
console.log(
|
|
33687
|
-
console.log(
|
|
33688
|
-
console.log(
|
|
33689
|
-
console.log(
|
|
33690
|
-
console.log(
|
|
34562
|
+
console.log(chalk76.dim(" Usage:"));
|
|
34563
|
+
console.log(chalk76.dim(" /exports list [kind]"));
|
|
34564
|
+
console.log(chalk76.dim(" /exports open"));
|
|
34565
|
+
console.log(chalk76.dim(" /exports move <id|filename> <dest-dir>"));
|
|
34566
|
+
console.log(chalk76.dim(" /inbox show | set <path> | skill | clear"));
|
|
33691
34567
|
}
|
|
33692
|
-
async function
|
|
34568
|
+
async function handler47(args, ctx) {
|
|
33693
34569
|
const sub = (args[0] ?? "").toLowerCase();
|
|
33694
34570
|
if (!sub) {
|
|
33695
34571
|
printInboxShow();
|
|
@@ -33716,7 +34592,7 @@ async function handler46(args, ctx) {
|
|
|
33716
34592
|
return await runInboxSet(args.slice(1), ctx);
|
|
33717
34593
|
case "clear":
|
|
33718
34594
|
clearAiInboxDir();
|
|
33719
|
-
console.log(" " +
|
|
34595
|
+
console.log(" " + chalk76.dim("AI inbox cleared. Files on disk were kept."));
|
|
33720
34596
|
return "AI inbox cleared";
|
|
33721
34597
|
default:
|
|
33722
34598
|
if (!["help", "-h", "--help"].includes(sub)) {
|
|
@@ -33732,40 +34608,40 @@ function printInboxShow() {
|
|
|
33732
34608
|
const inbox = getAiInboxDir();
|
|
33733
34609
|
console.log();
|
|
33734
34610
|
console.log(" " + bold("Exports"));
|
|
33735
|
-
console.log(" " +
|
|
33736
|
-
console.log(" " +
|
|
34611
|
+
console.log(" " + chalk76.dim("Archive: ") + archive);
|
|
34612
|
+
console.log(" " + chalk76.dim("Index: ") + archiveIndexPath());
|
|
33737
34613
|
if (inbox) {
|
|
33738
34614
|
console.log(" " + paint("accent", "AI inbox: ") + inbox);
|
|
33739
34615
|
const latest = inboxLatestHandoffPath();
|
|
33740
|
-
if (latest) console.log(" " +
|
|
33741
|
-
console.log(" " +
|
|
33742
|
-
console.log(" " +
|
|
34616
|
+
if (latest) console.log(" " + chalk76.dim("Latest handoff: ") + latest);
|
|
34617
|
+
console.log(" " + chalk76.dim("Finder skill: ") + join35(inbox, "SKILL.md"));
|
|
34618
|
+
console.log(" " + chalk76.dim("Reprint: ") + paint("accent", "/inbox skill"));
|
|
33743
34619
|
} else {
|
|
33744
|
-
console.log(" " +
|
|
34620
|
+
console.log(" " + chalk76.dim("AI inbox: (not set). Type ") + paint("accent", "/inbox set <folder>"));
|
|
33745
34621
|
}
|
|
33746
34622
|
const archLatest = archiveLatestHandoffPath();
|
|
33747
34623
|
if (archLatest) {
|
|
33748
|
-
console.log(" " +
|
|
34624
|
+
console.log(" " + chalk76.dim("Archive latest: ") + archLatest);
|
|
33749
34625
|
}
|
|
33750
34626
|
console.log();
|
|
33751
34627
|
}
|
|
33752
34628
|
function printOpen() {
|
|
33753
34629
|
console.log();
|
|
33754
34630
|
console.log(" " + bold("Open these paths"));
|
|
33755
|
-
console.log(" " +
|
|
34631
|
+
console.log(" " + chalk76.dim("INDEX: ") + archiveIndexPath());
|
|
33756
34632
|
const arch = archiveLatestHandoffPath();
|
|
33757
|
-
if (arch) console.log(" " +
|
|
34633
|
+
if (arch) console.log(" " + chalk76.dim("Latest handoff: ") + arch);
|
|
33758
34634
|
const inbox = getAiInboxDir();
|
|
33759
34635
|
if (inbox) {
|
|
33760
|
-
console.log(" " +
|
|
34636
|
+
console.log(" " + chalk76.dim("AI inbox: ") + inbox);
|
|
33761
34637
|
const latest = inboxLatestHandoffPath();
|
|
33762
|
-
if (latest) console.log(" " +
|
|
33763
|
-
console.log(" " +
|
|
33764
|
-
console.log(" " +
|
|
34638
|
+
if (latest) console.log(" " + chalk76.dim("Inbox latest: ") + latest);
|
|
34639
|
+
console.log(" " + chalk76.dim("Pickup skill: ") + join35(inbox, "latest-pickup.md"));
|
|
34640
|
+
console.log(" " + chalk76.dim("Finder skill: ") + join35(inbox, "SKILL.md"));
|
|
33765
34641
|
} else {
|
|
33766
|
-
console.log(" " +
|
|
34642
|
+
console.log(" " + chalk76.dim("AI inbox is not set. Type ") + paint("accent", "/inbox set <folder>"));
|
|
33767
34643
|
const loc = handoffLocations();
|
|
33768
|
-
console.log(" " +
|
|
34644
|
+
console.log(" " + chalk76.dim("Finder skill: ") + loc.archiveSkill);
|
|
33769
34645
|
}
|
|
33770
34646
|
console.log();
|
|
33771
34647
|
}
|
|
@@ -33773,17 +34649,17 @@ function printList(kind) {
|
|
|
33773
34649
|
const items = listExports({ limit: 20, kind: kind || void 0 });
|
|
33774
34650
|
console.log(" " + bold(kind ? `Recent exports (${kind})` : "Recent exports"));
|
|
33775
34651
|
if (items.length === 0) {
|
|
33776
|
-
console.log(" " +
|
|
34652
|
+
console.log(" " + chalk76.dim("None yet. Type /handoff prompt deck to write a handoff."));
|
|
33777
34653
|
console.log();
|
|
33778
34654
|
return;
|
|
33779
34655
|
}
|
|
33780
34656
|
for (const e of items) {
|
|
33781
|
-
const title = e.title ?
|
|
33782
|
-
console.log(` ${paint("accent", e.id)} ${e.kind} ${
|
|
34657
|
+
const title = e.title ? chalk76.dim(` \u2014 ${e.title}`) : "";
|
|
34658
|
+
console.log(` ${paint("accent", e.id)} ${e.kind} ${chalk76.dim(e.at)}${title}`);
|
|
33783
34659
|
console.log(` ${e.path}`);
|
|
33784
|
-
if (e.inbox_path) console.log(` ${
|
|
34660
|
+
if (e.inbox_path) console.log(` ${chalk76.dim("inbox:")} ${e.inbox_path}`);
|
|
33785
34661
|
if (e.previous_paths && e.previous_paths.length > 0) {
|
|
33786
|
-
console.log(` ${
|
|
34662
|
+
console.log(` ${chalk76.dim("was:")} ${e.previous_paths[e.previous_paths.length - 1]}`);
|
|
33787
34663
|
}
|
|
33788
34664
|
}
|
|
33789
34665
|
console.log();
|
|
@@ -33791,8 +34667,8 @@ function printList(kind) {
|
|
|
33791
34667
|
async function runInboxSet(args, ctx) {
|
|
33792
34668
|
const pathArg = args.join(" ").trim();
|
|
33793
34669
|
if (!pathArg) {
|
|
33794
|
-
console.error(
|
|
33795
|
-
console.error(
|
|
34670
|
+
console.error(chalk76.red(" Usage: /inbox set <path>"));
|
|
34671
|
+
console.error(chalk76.dim(" Example: /inbox set ~/Documents/Claude/ntrp-inbox"));
|
|
33796
34672
|
if (ctx.oneShot) process.exit(1);
|
|
33797
34673
|
return;
|
|
33798
34674
|
}
|
|
@@ -33806,25 +34682,25 @@ async function runInboxSet(args, ctx) {
|
|
|
33806
34682
|
true
|
|
33807
34683
|
);
|
|
33808
34684
|
if (!ok) {
|
|
33809
|
-
console.log(" " +
|
|
34685
|
+
console.log(" " + chalk76.dim("Cancelled."));
|
|
33810
34686
|
return;
|
|
33811
34687
|
}
|
|
33812
34688
|
} finally {
|
|
33813
34689
|
prompts.close();
|
|
33814
34690
|
}
|
|
33815
34691
|
} else {
|
|
33816
|
-
console.log(" " +
|
|
33817
|
-
console.log(" " +
|
|
34692
|
+
console.log(" " + chalk76.yellow(`Inbox is outside ~/.ntrp: ${resolved}`));
|
|
34693
|
+
console.log(" " + chalk76.dim("Handoffs with analysis text will be written here."));
|
|
33818
34694
|
}
|
|
33819
34695
|
}
|
|
33820
34696
|
const setTo = setAiInboxDir(pathArg);
|
|
33821
34697
|
const n = syncRecentToInbox(10);
|
|
33822
34698
|
console.log();
|
|
33823
34699
|
console.log(" " + paint("accent", "AI inbox set"));
|
|
33824
|
-
console.log(" " +
|
|
33825
|
-
console.log(" " +
|
|
34700
|
+
console.log(" " + chalk76.dim(setTo));
|
|
34701
|
+
console.log(" " + chalk76.dim("Point Claude Desktop or another desktop AI at this folder."));
|
|
33826
34702
|
if (n > 0) {
|
|
33827
|
-
console.log(" " +
|
|
34703
|
+
console.log(" " + chalk76.dim(`Synced ${n} recent export${n === 1 ? "" : "s"} into the inbox.`));
|
|
33828
34704
|
}
|
|
33829
34705
|
printStandingSkill();
|
|
33830
34706
|
return `AI inbox \u2192 ${setTo}`;
|
|
@@ -33833,28 +34709,28 @@ function runMove(args, ctx) {
|
|
|
33833
34709
|
const idOrName = args[0];
|
|
33834
34710
|
const dest = args.slice(1).join(" ").trim();
|
|
33835
34711
|
if (!idOrName || !dest) {
|
|
33836
|
-
console.error(
|
|
34712
|
+
console.error(chalk76.red(" Usage: /exports move <id|filename> <dest-dir>"));
|
|
33837
34713
|
if (ctx.oneShot) process.exit(1);
|
|
33838
34714
|
return;
|
|
33839
34715
|
}
|
|
33840
34716
|
try {
|
|
33841
34717
|
const destDir = resolveUserPath(dest);
|
|
33842
|
-
if (!
|
|
34718
|
+
if (!existsSync31(destDir)) {
|
|
33843
34719
|
}
|
|
33844
34720
|
const event = moveExport(idOrName, destDir);
|
|
33845
34721
|
console.log();
|
|
33846
34722
|
console.log(" " + paint("accent", "Moved export"));
|
|
33847
34723
|
for (const line of formatExportLocationLines(event)) {
|
|
33848
|
-
console.log(" " +
|
|
34724
|
+
console.log(" " + chalk76.dim(line));
|
|
33849
34725
|
}
|
|
33850
34726
|
if (event.previous_paths?.length) {
|
|
33851
|
-
console.log(" " +
|
|
34727
|
+
console.log(" " + chalk76.dim("Was: ") + event.previous_paths[event.previous_paths.length - 1]);
|
|
33852
34728
|
}
|
|
33853
|
-
console.log(" " +
|
|
34729
|
+
console.log(" " + chalk76.dim(`Trail recorded in ${archiveIndexPath()}`));
|
|
33854
34730
|
console.log();
|
|
33855
34731
|
return `Moved to ${event.path}`;
|
|
33856
34732
|
} catch (err) {
|
|
33857
|
-
console.error(
|
|
34733
|
+
console.error(chalk76.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
33858
34734
|
if (ctx.oneShot) process.exit(1);
|
|
33859
34735
|
}
|
|
33860
34736
|
}
|
|
@@ -33873,9 +34749,9 @@ var init_exports = __esm({
|
|
|
33873
34749
|
// src/commands/privacy.ts
|
|
33874
34750
|
var privacy_exports = {};
|
|
33875
34751
|
__export(privacy_exports, {
|
|
33876
|
-
handler: () =>
|
|
34752
|
+
handler: () => handler48
|
|
33877
34753
|
});
|
|
33878
|
-
async function
|
|
34754
|
+
async function handler48(_args, _ctx) {
|
|
33879
34755
|
console.log();
|
|
33880
34756
|
console.log(" " + bold("What leaves this machine"));
|
|
33881
34757
|
for (const line of PRIVACY_NOTICE_LINES) {
|
|
@@ -33980,10 +34856,10 @@ async function resolveHandler(name) {
|
|
|
33980
34856
|
try {
|
|
33981
34857
|
const mod = await importHandler(runtimePath);
|
|
33982
34858
|
if (!mod) return null;
|
|
33983
|
-
const
|
|
33984
|
-
if (typeof
|
|
33985
|
-
entry.handler =
|
|
33986
|
-
return
|
|
34859
|
+
const handler50 = mod.handler;
|
|
34860
|
+
if (typeof handler50 !== "function") return null;
|
|
34861
|
+
entry.handler = handler50;
|
|
34862
|
+
return handler50;
|
|
33987
34863
|
} catch (err) {
|
|
33988
34864
|
console.error(`Failed to load handler for /${name}:`, err);
|
|
33989
34865
|
return null;
|
|
@@ -34083,6 +34959,8 @@ async function importHandler(runtimePath) {
|
|
|
34083
34959
|
return Promise.resolve().then(() => (init_progress2(), progress_exports));
|
|
34084
34960
|
case "../commands/deepdive.js":
|
|
34085
34961
|
return Promise.resolve().then(() => (init_deepdive(), deepdive_exports));
|
|
34962
|
+
case "../commands/thinkwithme.js":
|
|
34963
|
+
return Promise.resolve().then(() => (init_thinkwithme(), thinkwithme_exports));
|
|
34086
34964
|
case "../commands/exports.js":
|
|
34087
34965
|
return Promise.resolve().then(() => (init_exports(), exports_exports));
|
|
34088
34966
|
case "../commands/privacy.js":
|
|
@@ -34549,6 +35427,21 @@ Bare \`/deepdive\` runs the full onboarding tour. Type \`/deepdive guide\` to ju
|
|
|
34549
35427
|
Type \`/deepdive handoff\` for the ship-to-Claude slide. Type \`/deepdive <metric>\` to jump to one metric card.
|
|
34550
35428
|
Type \`/deepdive list\` to print the catalog. Works without an AI key. Re-run anytime from the homescreen.
|
|
34551
35429
|
Live values overlay when an analysis exists.`
|
|
35430
|
+
},
|
|
35431
|
+
{
|
|
35432
|
+
name: "thinkwithme",
|
|
35433
|
+
raw: `---
|
|
35434
|
+
name: thinkwithme
|
|
35435
|
+
description: Socratic co-thinking channel \u2014 explore and pressure-test
|
|
35436
|
+
section: Navigation
|
|
35437
|
+
args: [topic]
|
|
35438
|
+
handler: ../commands/thinkwithme.ts
|
|
35439
|
+
---
|
|
35440
|
+
|
|
35441
|
+
Open a dedicated \`think \u203A\` channel to explore ideas, challenge assumptions, and pull evidence from your data.
|
|
35442
|
+
Bare \`/thinkwithme\` enters the channel. Type \`/thinkwithme <topic>\` to seed the first turn.
|
|
35443
|
+
Requires an analysis and an AI key (\`/connect\`). Type \`done\` or \`cancel\` to return to ask \u203A.
|
|
35444
|
+
When you are ready to commit to a plan, say so or the partner can hand off to \`/strategy\`.`
|
|
34552
35445
|
},
|
|
34553
35446
|
{
|
|
34554
35447
|
name: "status",
|
|
@@ -34787,11 +35680,11 @@ Cross-provider IDs are rejected. Type \`/provider\` first to switch.`
|
|
|
34787
35680
|
name: activate
|
|
34788
35681
|
description: Enter a license key
|
|
34789
35682
|
section: Settings
|
|
34790
|
-
args:
|
|
35683
|
+
args: [license]
|
|
34791
35684
|
handler: ../commands/activate.ts
|
|
34792
35685
|
---
|
|
34793
35686
|
|
|
34794
|
-
Activate NTRP with the key from your purchase email. Most commands need a valid license.`
|
|
35687
|
+
Activate NTRP with the key from your purchase email. Type \`/activate\` with no key to paste. Most commands need a valid license.`
|
|
34795
35688
|
},
|
|
34796
35689
|
{
|
|
34797
35690
|
name: "upgrade",
|
|
@@ -34836,7 +35729,7 @@ Remaining nuances merge into a custom_context paragraph that flows into all AI s
|
|
|
34836
35729
|
});
|
|
34837
35730
|
|
|
34838
35731
|
// src/ai/prompt-parts.ts
|
|
34839
|
-
import { existsSync as
|
|
35732
|
+
import { existsSync as existsSync32, readFileSync as readFileSync23 } from "fs";
|
|
34840
35733
|
import { join as join36 } from "path";
|
|
34841
35734
|
function buildCompanyProfileBlock() {
|
|
34842
35735
|
const p = loadProfile();
|
|
@@ -34857,7 +35750,7 @@ function buildCompanyProfileBlock() {
|
|
|
34857
35750
|
function loadAnalystFile() {
|
|
34858
35751
|
const path = join36(ntrpHome(), ANALYST_FILE_NAME);
|
|
34859
35752
|
try {
|
|
34860
|
-
if (!
|
|
35753
|
+
if (!existsSync32(path)) return null;
|
|
34861
35754
|
const raw = sanitizeExternalText(readFileSync23(path, "utf-8").trim());
|
|
34862
35755
|
if (!raw) return null;
|
|
34863
35756
|
if (raw.length <= ANALYST_FILE_MAX_CHARS) return raw;
|
|
@@ -35271,11 +36164,11 @@ __export(compute_exports2, {
|
|
|
35271
36164
|
isComputeIntent: () => isComputeIntent,
|
|
35272
36165
|
runConversationCompute: () => runConversationCompute
|
|
35273
36166
|
});
|
|
35274
|
-
import
|
|
36167
|
+
import chalk77 from "chalk";
|
|
35275
36168
|
async function runConversationCompute(ctx) {
|
|
35276
36169
|
const lens = ctx.scope?.primary_lens ?? ctx.analysis.primary;
|
|
35277
36170
|
ctx.computeInProgress = true;
|
|
35278
|
-
const willAnswer = Boolean(ctx.pendingAsk?.text) && !ctx.strategistState;
|
|
36171
|
+
const willAnswer = Boolean(ctx.pendingAsk?.text) && !ctx.strategistState && ctx.thinkState?.step !== "awaiting_analysis";
|
|
35279
36172
|
try {
|
|
35280
36173
|
if (lens === "revenue_metrics") {
|
|
35281
36174
|
const { runMetricsAnalysis: runMetricsAnalysis2, extractHeadlineMetrics: extractHeadlineMetrics2 } = await Promise.resolve().then(() => (init_metrics_analysis(), metrics_analysis_exports));
|
|
@@ -35303,6 +36196,7 @@ async function runConversationCompute(ctx) {
|
|
|
35303
36196
|
interactive: !willAnswer
|
|
35304
36197
|
});
|
|
35305
36198
|
await resumeQueuedStrategist(ctx);
|
|
36199
|
+
await resumeQueuedThink(ctx);
|
|
35306
36200
|
await closeComputeTurn(ctx, willAnswer, "revenue_metrics");
|
|
35307
36201
|
creditGapCompute(ctx);
|
|
35308
36202
|
creditMetricsComplete(ctx, false);
|
|
@@ -35322,11 +36216,12 @@ async function runConversationCompute(ctx) {
|
|
|
35322
36216
|
invalidateGapAudit(ctx);
|
|
35323
36217
|
saveSessionState(ctx);
|
|
35324
36218
|
await resumeQueuedStrategist(ctx);
|
|
36219
|
+
await resumeQueuedThink(ctx);
|
|
35325
36220
|
await closeComputeTurn(ctx, willAnswer, "gtm_health");
|
|
35326
36221
|
creditGapCompute(ctx);
|
|
35327
36222
|
return typeof summary === "string" ? summary : "Health analysis ready";
|
|
35328
36223
|
} catch (err) {
|
|
35329
|
-
console.error(" " +
|
|
36224
|
+
console.error(" " + chalk77.red(String(err.message ?? err)));
|
|
35330
36225
|
return;
|
|
35331
36226
|
} finally {
|
|
35332
36227
|
ctx.computeInProgress = false;
|
|
@@ -35339,9 +36234,16 @@ async function resumeQueuedStrategist(ctx) {
|
|
|
35339
36234
|
const { resumeStrategistAfterCompute: resumeStrategistAfterCompute2 } = await Promise.resolve().then(() => (init_strategist_flow(), strategist_flow_exports));
|
|
35340
36235
|
await resumeStrategistAfterCompute2(ctx);
|
|
35341
36236
|
}
|
|
36237
|
+
async function resumeQueuedThink(ctx) {
|
|
36238
|
+
if (ctx.thinkState?.step !== "awaiting_analysis") return;
|
|
36239
|
+
ctx.computeInProgress = false;
|
|
36240
|
+
const { resumeThinkAfterCompute: resumeThinkAfterCompute2 } = await Promise.resolve().then(() => (init_think_flow(), think_flow_exports));
|
|
36241
|
+
await resumeThinkAfterCompute2(ctx);
|
|
36242
|
+
}
|
|
35342
36243
|
async function resumePendingAskAfterCompute(ctx) {
|
|
35343
36244
|
if (!ctx.pendingAsk?.text) return false;
|
|
35344
36245
|
if (ctx.strategistState) return false;
|
|
36246
|
+
if (ctx.thinkState?.step === "active" || ctx.thinkState?.step === "awaiting_analysis") return false;
|
|
35345
36247
|
const { resumePendingAsk: resumePendingAsk2 } = await Promise.resolve().then(() => (init_pending_ask(), pending_ask_exports));
|
|
35346
36248
|
return resumePendingAsk2(ctx);
|
|
35347
36249
|
}
|
|
@@ -35375,10 +36277,10 @@ __export(ingest_chat_exports, {
|
|
|
35375
36277
|
loadDemoFromChat: () => loadDemoFromChat,
|
|
35376
36278
|
looksLikeFilePath: () => looksLikeFilePath
|
|
35377
36279
|
});
|
|
35378
|
-
import { existsSync as
|
|
36280
|
+
import { existsSync as existsSync33 } from "fs";
|
|
35379
36281
|
import { basename as basename9, resolve as resolve9 } from "path";
|
|
35380
36282
|
import { homedir as homedir8 } from "os";
|
|
35381
|
-
import
|
|
36283
|
+
import chalk78 from "chalk";
|
|
35382
36284
|
function extractFilePath(input) {
|
|
35383
36285
|
const trimmed = input.trim();
|
|
35384
36286
|
const patterns = [
|
|
@@ -35395,11 +36297,11 @@ function extractFilePath(input) {
|
|
|
35395
36297
|
const m = trimmed.match(re);
|
|
35396
36298
|
if (m?.[1]) {
|
|
35397
36299
|
const p = expandPath(m[1]);
|
|
35398
|
-
if (
|
|
36300
|
+
if (existsSync33(p)) return p;
|
|
35399
36301
|
}
|
|
35400
36302
|
if (!m?.[1] && re.test(trimmed) && trimmed.toLowerCase().endsWith(".csv")) {
|
|
35401
36303
|
const p = expandPath(trimmed.replace(/^["']|["']$/g, ""));
|
|
35402
|
-
if (
|
|
36304
|
+
if (existsSync33(p)) return p;
|
|
35403
36305
|
}
|
|
35404
36306
|
}
|
|
35405
36307
|
return null;
|
|
@@ -35413,7 +36315,7 @@ function looksLikeFilePath(input) {
|
|
|
35413
36315
|
}
|
|
35414
36316
|
async function ingestFromChat(ctx, filePath) {
|
|
35415
36317
|
if (!ctx.rl) {
|
|
35416
|
-
console.log(" " +
|
|
36318
|
+
console.log(" " + chalk78.red("Ingest confirm requires interactive mode."));
|
|
35417
36319
|
return false;
|
|
35418
36320
|
}
|
|
35419
36321
|
const name = basename9(filePath);
|
|
@@ -35421,7 +36323,7 @@ async function ingestFromChat(ctx, filePath) {
|
|
|
35421
36323
|
try {
|
|
35422
36324
|
const ok = await prompts.confirm(`Ingest ${name} as CRM export?`, true);
|
|
35423
36325
|
if (!ok) {
|
|
35424
|
-
console.log(" " +
|
|
36326
|
+
console.log(" " + chalk78.dim("Ingest cancelled."));
|
|
35425
36327
|
return false;
|
|
35426
36328
|
}
|
|
35427
36329
|
} finally {
|
|
@@ -35449,7 +36351,7 @@ async function ingestFromChat(ctx, filePath) {
|
|
|
35449
36351
|
true
|
|
35450
36352
|
);
|
|
35451
36353
|
if (useAi) {
|
|
35452
|
-
console.log(" " +
|
|
36354
|
+
console.log(" " + chalk78.dim("AI column mapping is not wired to ingest yet \u2014 trying standard ingest."));
|
|
35453
36355
|
}
|
|
35454
36356
|
} finally {
|
|
35455
36357
|
prompts2.close();
|
|
@@ -35476,7 +36378,7 @@ async function ingestFromChat(ctx, filePath) {
|
|
|
35476
36378
|
invalidateGapAudit(ctx);
|
|
35477
36379
|
saveSessionState(ctx);
|
|
35478
36380
|
console.log();
|
|
35479
|
-
console.log(" " + paint("accent", "\u2713 Data loaded") +
|
|
36381
|
+
console.log(" " + paint("accent", "\u2713 Data loaded") + chalk78.dim(` \u2014 ${name}`));
|
|
35480
36382
|
recordMessage(ctx, "user", `[ingested ${name}]`);
|
|
35481
36383
|
recordMessage(ctx, "agent", `Loaded ${name}. Checking what we can analyze\u2026`);
|
|
35482
36384
|
const audit = await refreshGapAudit(ctx);
|
|
@@ -35484,7 +36386,7 @@ async function ingestFromChat(ctx, filePath) {
|
|
|
35484
36386
|
if (audit.can_compute && ctx.scope?.confirmed_at) {
|
|
35485
36387
|
if (ctx.pendingAsk) {
|
|
35486
36388
|
console.log();
|
|
35487
|
-
console.log(" " +
|
|
36389
|
+
console.log(" " + chalk78.dim("Computing so I can answer\u2026"));
|
|
35488
36390
|
await runConversationCompute(ctx);
|
|
35489
36391
|
return true;
|
|
35490
36392
|
}
|
|
@@ -35532,7 +36434,7 @@ async function loadDemoFromChat(ctx, scenario, opts = {}) {
|
|
|
35532
36434
|
const { getScenario: getScenario2 } = await Promise.resolve().then(() => (init_scenarios(), scenarios_exports));
|
|
35533
36435
|
const s = getScenario2(chosen);
|
|
35534
36436
|
console.log();
|
|
35535
|
-
console.log(" " + paint("accent", "Fitting ") + s.label +
|
|
36437
|
+
console.log(" " + paint("accent", "Fitting ") + s.label + chalk78.dim(" \u2014 " + s.hook));
|
|
35536
36438
|
}
|
|
35537
36439
|
const { handler: demo } = await Promise.resolve().then(() => (init_generate(), generate_exports));
|
|
35538
36440
|
const args = ["--no-profile", "--brief"];
|
|
@@ -35568,7 +36470,7 @@ async function loadDemoFromChat(ctx, scenario, opts = {}) {
|
|
|
35568
36470
|
const shouldAuto = opts.autoCompute || Boolean(ctx.pendingAsk && audit.can_compute && ctx.scope?.confirmed_at);
|
|
35569
36471
|
if (shouldAuto && audit.can_compute) {
|
|
35570
36472
|
console.log();
|
|
35571
|
-
console.log(" " +
|
|
36473
|
+
console.log(" " + chalk78.dim("Computing so I can answer\u2026"));
|
|
35572
36474
|
await runConversationCompute(ctx);
|
|
35573
36475
|
return true;
|
|
35574
36476
|
}
|
|
@@ -35680,13 +36582,13 @@ __export(demo_fit_exports, {
|
|
|
35680
36582
|
resolveDemoScenarioForLoad: () => resolveDemoScenarioForLoad,
|
|
35681
36583
|
runDemoFitQuiz: () => runDemoFitQuiz
|
|
35682
36584
|
});
|
|
35683
|
-
import
|
|
36585
|
+
import chalk79 from "chalk";
|
|
35684
36586
|
async function runDemoFitQuiz(session, opts = {}) {
|
|
35685
36587
|
if (opts.intro !== false) {
|
|
35686
36588
|
console.log();
|
|
35687
36589
|
console.log(" " + bold("Fit a sample book of business"));
|
|
35688
36590
|
console.log(
|
|
35689
|
-
" " +
|
|
36591
|
+
" " + chalk79.dim(
|
|
35690
36592
|
"No API key needed. Two questions about how you sell, then you pick which of seven sample pipelines feels closest."
|
|
35691
36593
|
)
|
|
35692
36594
|
);
|
|
@@ -35704,8 +36606,8 @@ async function runDemoFitQuiz(session, opts = {}) {
|
|
|
35704
36606
|
);
|
|
35705
36607
|
const recommended = inferDemoScenario({ salesMotion: motion, dealBand });
|
|
35706
36608
|
console.log();
|
|
35707
|
-
console.log(" " +
|
|
35708
|
-
console.log(" " +
|
|
36609
|
+
console.log(" " + chalk79.dim("Recommended: ") + paint("accent", getScenario(recommended.scenario).label));
|
|
36610
|
+
console.log(" " + chalk79.dim(recommended.reason));
|
|
35709
36611
|
const scenario = await session.choose(
|
|
35710
36612
|
"Which of these sample books feels closest to the one you manage?",
|
|
35711
36613
|
scenarioMenuChoices(),
|
|
@@ -35725,8 +36627,8 @@ async function offerFittedDemoAfterOnboard(session, ctx, profile) {
|
|
|
35725
36627
|
const s = getScenario(fit.scenario);
|
|
35726
36628
|
console.log();
|
|
35727
36629
|
console.log(" " + bold("A sample pipeline that looks like you"));
|
|
35728
|
-
console.log(" " + paint("accent", s.label) +
|
|
35729
|
-
console.log(" " +
|
|
36630
|
+
console.log(" " + paint("accent", s.label) + chalk79.dim(" \u2014 " + s.hook));
|
|
36631
|
+
console.log(" " + chalk79.dim(fit.reason));
|
|
35730
36632
|
console.log();
|
|
35731
36633
|
const action = await session.choose(
|
|
35732
36634
|
"Try NTRP on that book of business?",
|
|
@@ -35783,8 +36685,8 @@ async function resolveDemoScenarioForLoad(ctx, opts = {}) {
|
|
|
35783
36685
|
if (!opts.forceQuiz && isProfileConfigured(profile) && profile) {
|
|
35784
36686
|
const fit = await resolveProfileFit(profile, ctx);
|
|
35785
36687
|
console.log();
|
|
35786
|
-
console.log(" " +
|
|
35787
|
-
console.log(" " +
|
|
36688
|
+
console.log(" " + chalk79.dim("Recommended: ") + paint("accent", getScenario(fit.scenario).label));
|
|
36689
|
+
console.log(" " + chalk79.dim(fit.reason));
|
|
35788
36690
|
const scenario = await session.choose(
|
|
35789
36691
|
"Which sample book of business?",
|
|
35790
36692
|
scenarioMenuChoices(),
|
|
@@ -35844,10 +36746,11 @@ __export(first_run_exports, {
|
|
|
35844
36746
|
loadFirstRunDemo: () => loadFirstRunDemo,
|
|
35845
36747
|
markFirstRunCompleted: () => markFirstRunCompleted,
|
|
35846
36748
|
printFirstRunChip: () => printFirstRunChip,
|
|
36749
|
+
resumeSetupAfterLicense: () => resumeSetupAfterLicense,
|
|
35847
36750
|
runFirstRunFork: () => runFirstRunFork,
|
|
35848
36751
|
shouldOfferFirstRunFork: () => shouldOfferFirstRunFork
|
|
35849
36752
|
});
|
|
35850
|
-
import
|
|
36753
|
+
import chalk80 from "chalk";
|
|
35851
36754
|
function hasCompletedFirstRun() {
|
|
35852
36755
|
return Boolean(getConfigValue(FIRST_RUN_KEY));
|
|
35853
36756
|
}
|
|
@@ -35873,7 +36776,7 @@ async function runFirstRunFork(ctx, options = {}) {
|
|
|
35873
36776
|
if (!options.skipBrand) printCenteredLogo();
|
|
35874
36777
|
console.log();
|
|
35875
36778
|
console.log(" " + bold("Welcome to NTRP"));
|
|
35876
|
-
console.log(" " +
|
|
36779
|
+
console.log(" " + chalk80.dim(TAGLINE));
|
|
35877
36780
|
console.log();
|
|
35878
36781
|
try {
|
|
35879
36782
|
const { offerFirstRunTour: offerFirstRunTour2 } = await Promise.resolve().then(() => (init_metric_tour(), metric_tour_exports));
|
|
@@ -35911,18 +36814,18 @@ async function runFirstRunFork(ctx, options = {}) {
|
|
|
35911
36814
|
await offerInboxSkillSetup2(session, { beat: "demo" });
|
|
35912
36815
|
const s = getScenario(picked.scenario);
|
|
35913
36816
|
console.log();
|
|
35914
|
-
console.log(" " + paint("accent", "Loading demo\u2026") +
|
|
36817
|
+
console.log(" " + paint("accent", "Loading demo\u2026") + chalk80.dim(" " + s.label + " \u2014 " + s.hook));
|
|
35915
36818
|
console.log();
|
|
35916
36819
|
markFirstRunCompleted();
|
|
35917
36820
|
return { choice: "demo", scenario: picked.scenario };
|
|
35918
36821
|
}
|
|
35919
36822
|
if (choice === "onboard") {
|
|
35920
|
-
console.log(" " +
|
|
36823
|
+
console.log(" " + chalk80.dim("Starting guided setup \u2014 key first, then your company profile."));
|
|
35921
36824
|
console.log();
|
|
35922
36825
|
markFirstRunCompleted();
|
|
35923
36826
|
return { choice: "onboard" };
|
|
35924
36827
|
}
|
|
35925
|
-
console.log(" " +
|
|
36828
|
+
console.log(" " + chalk80.dim("Type what you want to look at."));
|
|
35926
36829
|
console.log();
|
|
35927
36830
|
markFirstRunCompleted();
|
|
35928
36831
|
return { choice: "skip" };
|
|
@@ -35932,7 +36835,7 @@ async function runFirstRunFork(ctx, options = {}) {
|
|
|
35932
36835
|
}
|
|
35933
36836
|
function printFirstRunChip() {
|
|
35934
36837
|
console.log(
|
|
35935
|
-
" " +
|
|
36838
|
+
" " + chalk80.dim("No profile yet \u2014 ask a question, type ") + chalk80.cyan("use demo data") + chalk80.dim(", or ") + paint("accent", "/onboard") + chalk80.dim(" to calibrate.")
|
|
35936
36839
|
);
|
|
35937
36840
|
console.log();
|
|
35938
36841
|
}
|
|
@@ -35948,9 +36851,6 @@ async function completeInteractiveSetup(ctx, options = {}) {
|
|
|
35948
36851
|
await loadFirstRunDemo(ctx, fork.scenario);
|
|
35949
36852
|
}
|
|
35950
36853
|
}
|
|
35951
|
-
if (!isProfileConfigured()) {
|
|
35952
|
-
printFirstRunChip();
|
|
35953
|
-
}
|
|
35954
36854
|
} catch (err) {
|
|
35955
36855
|
if (err instanceof GlobalReplCommandError) {
|
|
35956
36856
|
if (err.command === "exit") {
|
|
@@ -35966,14 +36866,22 @@ async function completeInteractiveSetup(ctx, options = {}) {
|
|
|
35966
36866
|
await runGlobalAdminCommand2(err.command, `/${err.command}`, ctx);
|
|
35967
36867
|
}
|
|
35968
36868
|
markFirstRunCompleted();
|
|
35969
|
-
if (!isProfileConfigured()) {
|
|
35970
|
-
printFirstRunChip();
|
|
35971
|
-
}
|
|
35972
36869
|
return;
|
|
35973
36870
|
}
|
|
35974
36871
|
throw err;
|
|
35975
36872
|
}
|
|
35976
36873
|
}
|
|
36874
|
+
async function resumeSetupAfterLicense(ctx) {
|
|
36875
|
+
if (!hasValidLicense()) return false;
|
|
36876
|
+
if (!isProfileConfigured() && shouldOfferFirstRunFork()) {
|
|
36877
|
+
ctx.pendingBlockedLine = void 0;
|
|
36878
|
+
await completeInteractiveSetup(ctx, { skipBrand: true });
|
|
36879
|
+
return true;
|
|
36880
|
+
}
|
|
36881
|
+
const { replayPendingBlockedLine: replayPendingBlockedLine2 } = await Promise.resolve().then(() => (init_dispatch(), dispatch_exports));
|
|
36882
|
+
await replayPendingBlockedLine2(ctx);
|
|
36883
|
+
return false;
|
|
36884
|
+
}
|
|
35977
36885
|
async function loadFirstRunDemo(ctx, scenario) {
|
|
35978
36886
|
const { handler: demo } = await Promise.resolve().then(() => (init_generate(), generate_exports));
|
|
35979
36887
|
const ok = await demo(["--no-profile", "--scenario", scenario, "--brief"], ctx);
|
|
@@ -36007,6 +36915,7 @@ var init_first_run = __esm({
|
|
|
36007
36915
|
init_scenarios();
|
|
36008
36916
|
init_repl_globals();
|
|
36009
36917
|
init_global_admin();
|
|
36918
|
+
init_activation();
|
|
36010
36919
|
FIRST_RUN_KEY = "first-run-completed";
|
|
36011
36920
|
}
|
|
36012
36921
|
});
|
|
@@ -36014,24 +36923,24 @@ var init_first_run = __esm({
|
|
|
36014
36923
|
// src/commands/scratch.ts
|
|
36015
36924
|
var scratch_exports = {};
|
|
36016
36925
|
__export(scratch_exports, {
|
|
36017
|
-
handler: () =>
|
|
36926
|
+
handler: () => handler49
|
|
36018
36927
|
});
|
|
36019
|
-
import
|
|
36928
|
+
import chalk81 from "chalk";
|
|
36020
36929
|
function printScratchPreamble(includeProgress) {
|
|
36021
36930
|
console.log();
|
|
36022
|
-
console.log(" " +
|
|
36023
|
-
console.log(" " +
|
|
36024
|
-
console.log(" " +
|
|
36025
|
-
console.log(" " +
|
|
36026
|
-
console.log(" " +
|
|
36931
|
+
console.log(" " + chalk81.yellow.bold("This will permanently remove:"));
|
|
36932
|
+
console.log(" " + chalk81.dim(" \u2022 API key and all config.json settings"));
|
|
36933
|
+
console.log(" " + chalk81.dim(" \u2022 Company profile (you will set up again in this session)"));
|
|
36934
|
+
console.log(" " + chalk81.dim(" \u2022 All sessions and datasets"));
|
|
36935
|
+
console.log(" " + chalk81.dim(" \u2022 Demo taxonomy cache"));
|
|
36027
36936
|
if (includeProgress) {
|
|
36028
|
-
console.log(" " +
|
|
36937
|
+
console.log(" " + chalk81.dim(" \u2022 Progress (hours saved) and install identity"));
|
|
36029
36938
|
}
|
|
36030
36939
|
console.log();
|
|
36031
36940
|
if (includeProgress) {
|
|
36032
|
-
console.log(" " +
|
|
36941
|
+
console.log(" " + chalk81.dim("Preserved: memory, strategies, wins, knowledge, exports, audit"));
|
|
36033
36942
|
} else {
|
|
36034
|
-
console.log(" " +
|
|
36943
|
+
console.log(" " + chalk81.dim("Preserved: progress (hours saved), memory, strategies, wins, knowledge, exports, audit"));
|
|
36035
36944
|
}
|
|
36036
36945
|
console.log();
|
|
36037
36946
|
}
|
|
@@ -36052,8 +36961,9 @@ function resetContextAfterScratch(ctx) {
|
|
|
36052
36961
|
ctx.deliverIntent = false;
|
|
36053
36962
|
ctx.computeInProgress = false;
|
|
36054
36963
|
ctx.lastExchange = void 0;
|
|
36964
|
+
ctx.pendingBlockedLine = void 0;
|
|
36055
36965
|
}
|
|
36056
|
-
async function
|
|
36966
|
+
async function handler49(args, ctx) {
|
|
36057
36967
|
const { flags } = parseArgs2(args, ["confirm", "include-progress"]);
|
|
36058
36968
|
const confirmedFlag = getBool(flags, "confirm");
|
|
36059
36969
|
const includeProgress = getBool(flags, "include-progress");
|
|
@@ -36071,18 +36981,17 @@ async function handler48(args, ctx) {
|
|
|
36071
36981
|
resetContextAfterScratch(ctx);
|
|
36072
36982
|
await rotateToFreshSession(ctx);
|
|
36073
36983
|
await initSchema();
|
|
36074
|
-
console.log();
|
|
36075
|
-
const detail = includeProgress ? " \u2014 local config, data, and progress wiped." : " \u2014 local config and data wiped.";
|
|
36076
|
-
console.log(" " + paint("accent", "\u2713 Scratch complete") + chalk78.dim(detail));
|
|
36077
|
-
console.log();
|
|
36078
36984
|
if (ctx.oneShot) {
|
|
36985
|
+
console.log();
|
|
36986
|
+
const detail = includeProgress ? " \u2014 local config, data, and progress wiped." : " \u2014 local config and data wiped.";
|
|
36987
|
+
console.log(" " + paint("accent", "\u2713 Scratch complete") + chalk81.dim(detail));
|
|
36988
|
+
console.log();
|
|
36079
36989
|
console.log(
|
|
36080
|
-
" " +
|
|
36990
|
+
" " + chalk81.dim("Run ") + paint("accent", "ntrp") + chalk81.dim(" interactively to complete onboarding.\n")
|
|
36081
36991
|
);
|
|
36082
36992
|
return "Scratch complete";
|
|
36083
36993
|
}
|
|
36084
|
-
|
|
36085
|
-
console.log();
|
|
36994
|
+
clearSlideScreen();
|
|
36086
36995
|
const shown = await ensureLicenseActivated(ctx, { exitOnCancel: false });
|
|
36087
36996
|
if (!hasValidLicense()) {
|
|
36088
36997
|
return "Scratch complete \u2014 license required";
|
|
@@ -36100,6 +37009,7 @@ var init_scratch = __esm({
|
|
|
36100
37009
|
init_scratch_wipe();
|
|
36101
37010
|
init_schema();
|
|
36102
37011
|
init_theme();
|
|
37012
|
+
init_slides();
|
|
36103
37013
|
init_activation();
|
|
36104
37014
|
}
|
|
36105
37015
|
});
|
|
@@ -36115,16 +37025,16 @@ async function runGlobalAdminCommand(command, line, ctx) {
|
|
|
36115
37025
|
const args = tokens.slice(1);
|
|
36116
37026
|
switch (command) {
|
|
36117
37027
|
case "scratch": {
|
|
36118
|
-
const { handler:
|
|
36119
|
-
return
|
|
37028
|
+
const { handler: handler50 } = await Promise.resolve().then(() => (init_scratch(), scratch_exports));
|
|
37029
|
+
return handler50(args, ctx);
|
|
36120
37030
|
}
|
|
36121
37031
|
case "cleanup": {
|
|
36122
|
-
const { handler:
|
|
36123
|
-
return
|
|
37032
|
+
const { handler: handler50 } = await Promise.resolve().then(() => (init_cleanup(), cleanup_exports));
|
|
37033
|
+
return handler50(args, ctx);
|
|
36124
37034
|
}
|
|
36125
37035
|
case "deactivate-demo": {
|
|
36126
|
-
const { handler:
|
|
36127
|
-
return
|
|
37036
|
+
const { handler: handler50 } = await Promise.resolve().then(() => (init_deactivate_demo(), deactivate_demo_exports));
|
|
37037
|
+
return handler50(args, ctx);
|
|
36128
37038
|
}
|
|
36129
37039
|
default:
|
|
36130
37040
|
return void 0;
|
|
@@ -36151,8 +37061,13 @@ function resolvePostAction(input) {
|
|
|
36151
37061
|
if (cancelled || isCancelledSummary(summary)) return "none";
|
|
36152
37062
|
if (command === "onboard" && !ctx.replStarted) return "none";
|
|
36153
37063
|
if (HOME_COMMANDS.has(command)) return "home";
|
|
37064
|
+
if (command === "update" && isUpdateRestartFallback(summary)) return "home";
|
|
36154
37065
|
return "none";
|
|
36155
37066
|
}
|
|
37067
|
+
function isUpdateRestartFallback(summary) {
|
|
37068
|
+
if (!summary) return false;
|
|
37069
|
+
return /^Restart NTRP to use v/.test(summary);
|
|
37070
|
+
}
|
|
36156
37071
|
var HOME_COMMANDS;
|
|
36157
37072
|
var init_post_action = __esm({
|
|
36158
37073
|
"src/cli/post-action.ts"() {
|
|
@@ -36203,13 +37118,17 @@ var router_exports = {};
|
|
|
36203
37118
|
__export(router_exports, {
|
|
36204
37119
|
conversationRouter: () => conversationRouter
|
|
36205
37120
|
});
|
|
36206
|
-
import
|
|
37121
|
+
import chalk82 from "chalk";
|
|
36207
37122
|
function popModalState(ctx) {
|
|
36208
37123
|
const popped = [];
|
|
36209
37124
|
if (ctx.strategistState) {
|
|
36210
37125
|
ctx.strategistState = void 0;
|
|
36211
37126
|
popped.push("strategy session");
|
|
36212
37127
|
}
|
|
37128
|
+
if (ctx.thinkState) {
|
|
37129
|
+
ctx.thinkState = void 0;
|
|
37130
|
+
popped.push("think channel");
|
|
37131
|
+
}
|
|
36213
37132
|
if (ctx.deliverIntent) {
|
|
36214
37133
|
ctx.deliverIntent = false;
|
|
36215
37134
|
popped.push("handoff draft");
|
|
@@ -36233,7 +37152,7 @@ async function conversationRouter(input, ctx) {
|
|
|
36233
37152
|
if (FRESH_START_RE.test(line)) {
|
|
36234
37153
|
console.log();
|
|
36235
37154
|
console.log(
|
|
36236
|
-
" " +
|
|
37155
|
+
" " + chalk82.dim("Start a fresh analysis? This keeps prior sessions \u2014 say ") + chalk82.cyan("yes") + chalk82.dim(" to confirm or ") + chalk82.cyan("/home") + chalk82.dim(" for the dashboard.")
|
|
36237
37156
|
);
|
|
36238
37157
|
console.log();
|
|
36239
37158
|
return { handled: true };
|
|
@@ -36247,7 +37166,7 @@ async function conversationRouter(input, ctx) {
|
|
|
36247
37166
|
const backTo = formatPhaseLabel(resolveConversationPhase(ctx));
|
|
36248
37167
|
console.log();
|
|
36249
37168
|
console.log(
|
|
36250
|
-
" " +
|
|
37169
|
+
" " + chalk82.dim(`Cancelled \u2014 dropped ${popped.join(" and ")}. Back to `) + chalk82.cyan(backTo) + chalk82.dim(".")
|
|
36251
37170
|
);
|
|
36252
37171
|
console.log();
|
|
36253
37172
|
return { handled: true, summary: "Cancelled" };
|
|
@@ -36282,6 +37201,10 @@ async function conversationRouter(input, ctx) {
|
|
|
36282
37201
|
const summary = await handleStrategizeFlow(line, ctx) ?? void 0;
|
|
36283
37202
|
return { handled: true, summary };
|
|
36284
37203
|
}
|
|
37204
|
+
if (phase === "think") {
|
|
37205
|
+
const summary = await handleThinkFlow(line, ctx) ?? void 0;
|
|
37206
|
+
return { handled: true, summary };
|
|
37207
|
+
}
|
|
36285
37208
|
if (isStrategistIntent(line)) {
|
|
36286
37209
|
if (phase === "explore" || isAnalysisReady(ctx)) {
|
|
36287
37210
|
const summary = await startStrategistFlow(ctx, { seed: extractObjectiveSeed(line), origin: "nl" }) ?? void 0;
|
|
@@ -36291,6 +37214,15 @@ async function conversationRouter(input, ctx) {
|
|
|
36291
37214
|
queueStrategistForAnalysis(ctx, { seed: extractObjectiveSeed(line), origin: "nl" });
|
|
36292
37215
|
}
|
|
36293
37216
|
}
|
|
37217
|
+
if (isThinkIntent(line)) {
|
|
37218
|
+
if (phase === "explore" || isAnalysisReady(ctx)) {
|
|
37219
|
+
const summary = await startThinkFlow(ctx, { seed: extractThinkSeed(line), origin: "nl" }) ?? void 0;
|
|
37220
|
+
return { handled: true, summary };
|
|
37221
|
+
}
|
|
37222
|
+
if (phase === "orient" || phase === "scope" || phase === "awaiting_data") {
|
|
37223
|
+
queueThinkForAnalysis(ctx, { seed: extractThinkSeed(line), origin: "nl" });
|
|
37224
|
+
}
|
|
37225
|
+
}
|
|
36294
37226
|
if (isShipIntent(line) && (phase === "explore" || isAnalysisReady(ctx))) {
|
|
36295
37227
|
ctx.deliverIntent = true;
|
|
36296
37228
|
const summary = await handleDeliverFlow(line, ctx) ?? void 0;
|
|
@@ -36307,7 +37239,7 @@ async function conversationRouter(input, ctx) {
|
|
|
36307
37239
|
}
|
|
36308
37240
|
if (phase === "compute") {
|
|
36309
37241
|
console.log();
|
|
36310
|
-
console.log(" " +
|
|
37242
|
+
console.log(" " + chalk82.dim("Analysis running \u2014 wait for it to finish before typing another question."));
|
|
36311
37243
|
console.log();
|
|
36312
37244
|
return { handled: true };
|
|
36313
37245
|
}
|
|
@@ -36341,6 +37273,7 @@ var init_router = __esm({
|
|
|
36341
37273
|
init_orchestrator();
|
|
36342
37274
|
init_handoff_draft();
|
|
36343
37275
|
init_strategist_flow();
|
|
37276
|
+
init_think_flow();
|
|
36344
37277
|
init_context2();
|
|
36345
37278
|
init_demo();
|
|
36346
37279
|
FRESH_START_RE = /\b(start (over|fresh)|new analysis|start again|reset session)\b/i;
|
|
@@ -36354,7 +37287,7 @@ __export(dispatch_exports, {
|
|
|
36354
37287
|
dispatch: () => dispatch,
|
|
36355
37288
|
replayPendingBlockedLine: () => replayPendingBlockedLine
|
|
36356
37289
|
});
|
|
36357
|
-
import
|
|
37290
|
+
import chalk83 from "chalk";
|
|
36358
37291
|
function printLicenseRequired(command) {
|
|
36359
37292
|
printLicenseBlocked(command);
|
|
36360
37293
|
}
|
|
@@ -36372,7 +37305,7 @@ async function replayPendingBlockedLine(ctx) {
|
|
|
36372
37305
|
if (!hasValidLicense()) return false;
|
|
36373
37306
|
ctx.pendingBlockedLine = void 0;
|
|
36374
37307
|
console.log();
|
|
36375
|
-
console.log(" " +
|
|
37308
|
+
console.log(" " + chalk83.dim("Picking up where you left off\u2026"));
|
|
36376
37309
|
console.log();
|
|
36377
37310
|
await dispatch(line, ctx);
|
|
36378
37311
|
return true;
|
|
@@ -36442,7 +37375,7 @@ async function dispatch(input, ctx) {
|
|
|
36442
37375
|
if (tokens.length === 1) {
|
|
36443
37376
|
if (/^\d$/.test(first)) {
|
|
36444
37377
|
console.log(
|
|
36445
|
-
" " +
|
|
37378
|
+
" " + chalk83.dim("Looks like a menu pick \u2014 run ") + paint("accent", "/new") + chalk83.dim(" to start (pick Demo, then choose your analysis type).")
|
|
36446
37379
|
);
|
|
36447
37380
|
return { kind: "handled" };
|
|
36448
37381
|
}
|
|
@@ -36465,22 +37398,22 @@ async function dispatch(input, ctx) {
|
|
|
36465
37398
|
return { kind: "handled", summary };
|
|
36466
37399
|
}
|
|
36467
37400
|
console.log(
|
|
36468
|
-
" " +
|
|
37401
|
+
" " + chalk83.dim("Not in Q&A yet. Confirm the scope, load data, and run analysis first. Type ") + paint("accent", "/home") + chalk83.dim(" for status.")
|
|
36469
37402
|
);
|
|
36470
37403
|
return { kind: "handled" };
|
|
36471
37404
|
}
|
|
36472
37405
|
console.log(
|
|
36473
|
-
" " +
|
|
37406
|
+
" " + chalk83.dim("Natural-language questions run inside ntrp. Start with ") + paint("accent", "ntrp") + chalk83.dim(" and type a question after analysis.")
|
|
36474
37407
|
);
|
|
36475
37408
|
return { kind: "handled" };
|
|
36476
37409
|
}
|
|
36477
37410
|
async function runSlashCommand(name, args, ctx) {
|
|
36478
|
-
const
|
|
36479
|
-
if (!
|
|
36480
|
-
console.error(
|
|
37411
|
+
const handler50 = await resolveHandler(name);
|
|
37412
|
+
if (!handler50) {
|
|
37413
|
+
console.error(chalk83.red(` Unknown command: /${name}`));
|
|
36481
37414
|
return void 0;
|
|
36482
37415
|
}
|
|
36483
|
-
const result = await
|
|
37416
|
+
const result = await handler50(args, ctx);
|
|
36484
37417
|
return result ?? void 0;
|
|
36485
37418
|
}
|
|
36486
37419
|
async function runNaturalLanguage2(input, ctx) {
|
|
@@ -36514,7 +37447,7 @@ var init_inline_suggestion = __esm({
|
|
|
36514
37447
|
});
|
|
36515
37448
|
|
|
36516
37449
|
// src/conversation/loop-guard.ts
|
|
36517
|
-
import
|
|
37450
|
+
import chalk84 from "chalk";
|
|
36518
37451
|
function createLoopGuardState() {
|
|
36519
37452
|
return { phase: null, stuckTurns: 0 };
|
|
36520
37453
|
}
|
|
@@ -36546,10 +37479,10 @@ function printLoopEscalation(phase) {
|
|
|
36546
37479
|
if (!guide) return;
|
|
36547
37480
|
console.log();
|
|
36548
37481
|
console.log(
|
|
36549
|
-
" " +
|
|
37482
|
+
" " + chalk84.yellow("We seem to be going in circles \u2014 you're in ") + paint("accent", guide.mode) + chalk84.yellow(" mode.")
|
|
36550
37483
|
);
|
|
36551
|
-
console.log(" " +
|
|
36552
|
-
console.log(" " +
|
|
37484
|
+
console.log(" " + chalk84.dim("Right now I can only accept: ") + guide.accepts);
|
|
37485
|
+
console.log(" " + chalk84.dim("To leave: ") + guide.leave);
|
|
36553
37486
|
console.log();
|
|
36554
37487
|
}
|
|
36555
37488
|
var LOOP_GUARD_THRESHOLD, MODAL_PHASES, PHASE_GUIDES;
|
|
@@ -36592,7 +37525,7 @@ __export(welcome_exports, {
|
|
|
36592
37525
|
printWelcome: () => printWelcome,
|
|
36593
37526
|
resolveWelcomeNextAction: () => resolveWelcomeNextAction
|
|
36594
37527
|
});
|
|
36595
|
-
import
|
|
37528
|
+
import chalk85 from "chalk";
|
|
36596
37529
|
function formatHomeEntityCounts(counts) {
|
|
36597
37530
|
const parts = [];
|
|
36598
37531
|
const people = counts.people ?? 0;
|
|
@@ -36605,11 +37538,26 @@ function formatHomeEntityCounts(counts) {
|
|
|
36605
37538
|
if (acts > 0) parts.push(`${acts} ${acts === 1 ? "activity" : "activities"}`);
|
|
36606
37539
|
return parts.join(" \xB7 ");
|
|
36607
37540
|
}
|
|
36608
|
-
function formatEmptyDataHomeHint(savedSessionCount) {
|
|
37541
|
+
function formatEmptyDataHomeHint(savedSessionCount, opts = {}) {
|
|
37542
|
+
const onboard = opts.includeOnboard === true ? chalk85.dim(", or ") + paint("accent", "/onboard") + chalk85.dim(" to calibrate") : "";
|
|
36609
37543
|
if (savedSessionCount > 0) {
|
|
36610
|
-
return
|
|
37544
|
+
return chalk85.dim("Type ") + paint("accent", "use demo data") + chalk85.dim(" to load a sample") + onboard + chalk85.dim(". Type ") + paint("accent", "/session") + chalk85.dim(" to open a saved session");
|
|
37545
|
+
}
|
|
37546
|
+
return chalk85.dim("Type ") + paint("accent", "use demo data") + chalk85.dim(" to load a sample pipeline") + onboard;
|
|
37547
|
+
}
|
|
37548
|
+
function ntrpStatusRow(version, update) {
|
|
37549
|
+
if (update && isNewerVersion(update.latest, version)) {
|
|
37550
|
+
return {
|
|
37551
|
+
label: "ntrp",
|
|
37552
|
+
state: badge("UPDATE", "warning"),
|
|
37553
|
+
detail: `v${update.latest} \xB7 type /update`
|
|
37554
|
+
};
|
|
36611
37555
|
}
|
|
36612
|
-
return
|
|
37556
|
+
return {
|
|
37557
|
+
label: "ntrp",
|
|
37558
|
+
state: chalk85.dim(`v${version}`),
|
|
37559
|
+
detail: ""
|
|
37560
|
+
};
|
|
36613
37561
|
}
|
|
36614
37562
|
function resolveSessionSummary(input) {
|
|
36615
37563
|
if (input.scope?.intent_summary?.trim()) return input.scope.intent_summary.trim();
|
|
@@ -36644,19 +37592,19 @@ function sessionSummaryText(s) {
|
|
|
36644
37592
|
summary: s.summary,
|
|
36645
37593
|
dataset: s.dataset
|
|
36646
37594
|
});
|
|
36647
|
-
return summary === NO_SUMMARY ?
|
|
37595
|
+
return summary === NO_SUMMARY ? chalk85.dim(summary) : summary;
|
|
36648
37596
|
}
|
|
36649
37597
|
function formatLastSessionLine(s, colW, ctx, opts) {
|
|
36650
37598
|
const phase = sessionPhaseLabel(s, ctx);
|
|
36651
|
-
const current = opts?.markCurrent && s.id === ctx?.sessionId ?
|
|
36652
|
-
const meta = `${formatSessionId(s.id, s.name)} ${
|
|
37599
|
+
const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk85.dim(" \xB7 current") : "";
|
|
37600
|
+
const meta = `${formatSessionId(s.id, s.name)} ${chalk85.dim("\xB7")} ${chalk85.dim(lensBadgeLabel(s.analysis))} ${chalk85.dim("\xB7")} ${paint("accent", phase)} ${chalk85.dim("\xB7")} ${sessionSummaryText(s)}${current}`;
|
|
36653
37601
|
return truncateVisible(` ${meta}`, colW);
|
|
36654
37602
|
}
|
|
36655
37603
|
function formatActiveSessionLine(s, colW, ctx, opts) {
|
|
36656
37604
|
const indent = " ";
|
|
36657
37605
|
const idPart = formatSessionId(s.id, s.name);
|
|
36658
|
-
const status =
|
|
36659
|
-
const current = opts?.markCurrent && s.id === ctx?.sessionId ?
|
|
37606
|
+
const status = chalk85.dim(` \xB7 ${sessionStatusSuffix(s)}`);
|
|
37607
|
+
const current = opts?.markCurrent && s.id === ctx?.sessionId ? chalk85.dim(" \xB7 current") : "";
|
|
36660
37608
|
const suffix = `${status}${current}`;
|
|
36661
37609
|
const summaryBudget = Math.max(8, colW - visibleWidth(indent) - visibleWidth(idPart) - visibleWidth(suffix) - 2);
|
|
36662
37610
|
const summaryPart = truncateVisible(sessionSummaryText(s), summaryBudget);
|
|
@@ -36665,7 +37613,7 @@ function formatActiveSessionLine(s, colW, ctx, opts) {
|
|
|
36665
37613
|
function resolveWelcomeNextAction(input) {
|
|
36666
37614
|
const { profileReady, hasData, ctx, unfinishedCount, licenseValid } = input;
|
|
36667
37615
|
if (!licenseValid) {
|
|
36668
|
-
return { label: "Next:", command: "/
|
|
37616
|
+
return { label: "Next:", command: "/activate", detail: "paste a trial or Pro key" };
|
|
36669
37617
|
}
|
|
36670
37618
|
if (!profileReady && !hasData) {
|
|
36671
37619
|
return { label: "Try:", command: "", detail: 'type what you want to investigate (e.g. "pipeline health")' };
|
|
@@ -36697,13 +37645,13 @@ function buildSystemLines(colW, statusRows, recent) {
|
|
|
36697
37645
|
lines.push(sectionHeading("System"));
|
|
36698
37646
|
const labelW = Math.max(...statusRows.map((r) => r.label.length), "last used".length);
|
|
36699
37647
|
for (const item of statusRows) {
|
|
36700
|
-
const label =
|
|
37648
|
+
const label = chalk85.dim(padRight(item.label, labelW));
|
|
36701
37649
|
const state2 = padRight(item.state, 10);
|
|
36702
37650
|
const detailW = Math.max(1, colW - labelW - 13);
|
|
36703
|
-
lines.push(`${label} ${state2} ${
|
|
37651
|
+
lines.push(`${label} ${state2} ${chalk85.dim(truncateVisible(item.detail, detailW))}`);
|
|
36704
37652
|
}
|
|
36705
37653
|
if (recent) {
|
|
36706
|
-
lines.push(`${
|
|
37654
|
+
lines.push(`${chalk85.dim(padRight("last used", labelW))} ${chalk85.dim(recent)}`);
|
|
36707
37655
|
}
|
|
36708
37656
|
return lines;
|
|
36709
37657
|
}
|
|
@@ -36711,10 +37659,10 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
|
|
|
36711
37659
|
const lines = [""];
|
|
36712
37660
|
lines.push(sectionHeading("Last Session"));
|
|
36713
37661
|
if (!lastSession) {
|
|
36714
|
-
lines.push(` ${
|
|
37662
|
+
lines.push(` ${chalk85.dim("(none)")}`);
|
|
36715
37663
|
lines.push(
|
|
36716
37664
|
truncateVisible(
|
|
36717
|
-
` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${
|
|
37665
|
+
` ${nextAction.command ? actionHint(nextAction.label, nextAction.command, nextAction.detail) : `${chalk85.dim(nextAction.label)} ${chalk85.dim(nextAction.detail)}`}`,
|
|
36718
37666
|
colW
|
|
36719
37667
|
)
|
|
36720
37668
|
);
|
|
@@ -36728,7 +37676,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
|
|
|
36728
37676
|
if (!isCurrent) {
|
|
36729
37677
|
lines.push(
|
|
36730
37678
|
truncateVisible(
|
|
36731
|
-
` ${
|
|
37679
|
+
` ${chalk85.dim("Resume:")} ${paint("accent", `/session ${lastSession.id.slice(-4)}`)}`,
|
|
36732
37680
|
colW
|
|
36733
37681
|
)
|
|
36734
37682
|
);
|
|
@@ -36737,7 +37685,7 @@ function buildLastSessionLines(colW, ctx, lastSession, nextAction, emptyDataHint
|
|
|
36737
37685
|
truncateVisible(` ${actionHint(nextAction.label, nextAction.command, nextAction.detail)}`, colW)
|
|
36738
37686
|
);
|
|
36739
37687
|
} else {
|
|
36740
|
-
lines.push(truncateVisible(` ${
|
|
37688
|
+
lines.push(truncateVisible(` ${chalk85.dim(nextAction.label)} ${chalk85.dim(nextAction.detail)}`, colW));
|
|
36741
37689
|
}
|
|
36742
37690
|
if (isCurrent && emptyDataHint) {
|
|
36743
37691
|
lines.push(truncateVisible(` ${emptyDataHint}`, colW));
|
|
@@ -36748,18 +37696,20 @@ function buildActiveSessionsLines(colW, ctx, activeSessions) {
|
|
|
36748
37696
|
const lines = [""];
|
|
36749
37697
|
lines.push(sectionHeading("Active Sessions"));
|
|
36750
37698
|
if (activeSessions.length === 0) {
|
|
36751
|
-
lines.push(` ${
|
|
37699
|
+
lines.push(` ${chalk85.dim("(none in progress)")}`);
|
|
36752
37700
|
return lines;
|
|
36753
37701
|
}
|
|
36754
37702
|
for (const s of activeSessions.slice(0, 5)) {
|
|
36755
37703
|
lines.push(formatActiveSessionLine(s, colW, ctx, { markCurrent: true }));
|
|
36756
37704
|
}
|
|
36757
37705
|
if (activeSessions.length > 5) {
|
|
36758
|
-
lines.push(` ${
|
|
37706
|
+
lines.push(` ${chalk85.dim(`+${activeSessions.length - 5} more \xB7 `)}${paint("accent", "/session")}`);
|
|
36759
37707
|
}
|
|
36760
37708
|
return lines;
|
|
36761
37709
|
}
|
|
36762
37710
|
async function printWelcome(ctx, version) {
|
|
37711
|
+
const updateForPaint = ctx.updateAvailable;
|
|
37712
|
+
ctx.updateHomePaintedLatest = updateForPaint?.latest;
|
|
36763
37713
|
const width = termWidth();
|
|
36764
37714
|
const cardW = resolveCardWidth({ min: 72, max: CARD_MAX_W, margin: CARD_SIDE_MARGIN * 2 });
|
|
36765
37715
|
const innerW = cardW - 2;
|
|
@@ -36810,13 +37760,13 @@ async function printWelcome(ctx, version) {
|
|
|
36810
37760
|
const { countAvailableEngines: countAvailableEngines2, formatActiveStack: formatActiveStack2 } = await Promise.resolve().then(() => (init_session_state(), session_state_exports));
|
|
36811
37761
|
const engineCount = countAvailableEngines2();
|
|
36812
37762
|
const llmDetail = engineCount === 0 ? "paste a key. Type /connect" : formatActiveStack2(ctx);
|
|
36813
|
-
const llmState = engineCount > 0 ? badge("READY", "success") :
|
|
37763
|
+
const llmState = engineCount > 0 ? badge("READY", "success") : chalk85.dim("\u2014");
|
|
36814
37764
|
const license = checkLicense();
|
|
36815
37765
|
let licenseState;
|
|
36816
37766
|
let licenseDetail;
|
|
36817
37767
|
if (!license.valid) {
|
|
36818
37768
|
licenseState = badge("NOT SET", "warning");
|
|
36819
|
-
licenseDetail = "type /
|
|
37769
|
+
licenseDetail = "type /activate";
|
|
36820
37770
|
} else if (license.edition === "trial" && license.trialPhase === "grace") {
|
|
36821
37771
|
licenseState = badge("GRACE", "warning");
|
|
36822
37772
|
licenseDetail = `${license.daysUntilLockout ?? 0} day${license.daysUntilLockout === 1 ? "" : "s"} left on trial`;
|
|
@@ -36832,6 +37782,7 @@ async function printWelcome(ctx, version) {
|
|
|
36832
37782
|
licenseDetail = license.message;
|
|
36833
37783
|
}
|
|
36834
37784
|
const statusRows = [
|
|
37785
|
+
ntrpStatusRow(version, updateForPaint),
|
|
36835
37786
|
{
|
|
36836
37787
|
label: "license",
|
|
36837
37788
|
state: licenseState,
|
|
@@ -36860,7 +37811,7 @@ async function printWelcome(ctx, version) {
|
|
|
36860
37811
|
unfinishedCount: unfinishedSessions.length,
|
|
36861
37812
|
licenseValid: license.valid
|
|
36862
37813
|
});
|
|
36863
|
-
const emptyDataHint = !hasData ? formatEmptyDataHomeHint(savedSessions.length) : null;
|
|
37814
|
+
const emptyDataHint = !hasData && license.valid ? formatEmptyDataHomeHint(savedSessions.length, { includeOnboard: !profileReady }) : null;
|
|
36864
37815
|
const colW = useWideLayout ? leftW : contentW;
|
|
36865
37816
|
const rightColW = useWideLayout ? rightW : contentW;
|
|
36866
37817
|
const systemLines = buildSystemLines(colW, statusRows, recent);
|
|
@@ -36874,14 +37825,14 @@ async function printWelcome(ctx, version) {
|
|
|
36874
37825
|
const logoOffset = " ".repeat(Math.max(0, Math.floor((cardW - maxLogoW) / 2)));
|
|
36875
37826
|
for (const line of logo) push(logoOffset + line);
|
|
36876
37827
|
const taglineOffset = " ".repeat(Math.max(0, Math.floor((cardW - visibleWidth(TAGLINE)) / 2)));
|
|
36877
|
-
push(taglineOffset +
|
|
37828
|
+
push(taglineOffset + chalk85.dim(TAGLINE));
|
|
36878
37829
|
push("");
|
|
36879
37830
|
}
|
|
36880
37831
|
const versionTag = ` v${version} `;
|
|
36881
37832
|
const gap = Math.max(0, innerW - versionTag.length);
|
|
36882
37833
|
const gapL = Math.floor(gap / 2);
|
|
36883
37834
|
push(
|
|
36884
|
-
border(`\u256D${"\u2500".repeat(gapL)}`) +
|
|
37835
|
+
border(`\u256D${"\u2500".repeat(gapL)}`) + chalk85.dim(versionTag) + border(`${"\u2500".repeat(gap - gapL)}\u256E`)
|
|
36885
37836
|
);
|
|
36886
37837
|
if (useWideLayout) {
|
|
36887
37838
|
const leftLines = systemLines;
|
|
@@ -36908,21 +37859,21 @@ async function printWelcome(ctx, version) {
|
|
|
36908
37859
|
push(border(`\u2570${"\u2500".repeat(innerW)}\u256F`));
|
|
36909
37860
|
push(
|
|
36910
37861
|
truncateVisible(
|
|
36911
|
-
` ${paint("accent", "/help")}${
|
|
37862
|
+
license.valid ? ` ${paint("accent", "/help")}${chalk85.dim(" commands \xB7 ")}${paint("accent", "/deepdive")}${chalk85.dim(" tour \xB7 ")}${paint("accent", "/progress")}${chalk85.dim(" hours \xB7 ")}${paint("accent", "/session")}${chalk85.dim(" resume")}` : ` ${paint("accent", "/help")}${chalk85.dim(" commands \xB7 ")}${paint("accent", "/activate")}${chalk85.dim(" paste a key \xB7 ")}${paint("accent", "/checkout")}${chalk85.dim(" signup \xB7 ")}${paint("accent", "/progress")}${chalk85.dim(" hours")}`,
|
|
36912
37863
|
cardW
|
|
36913
37864
|
)
|
|
36914
37865
|
);
|
|
36915
37866
|
if (strategyNudge) {
|
|
36916
37867
|
push(
|
|
36917
37868
|
truncateVisible(
|
|
36918
|
-
` ${paint("warning", "\u2691")} ${
|
|
37869
|
+
` ${paint("warning", "\u2691")} ${chalk85.dim(strategyNudge.text)} ${chalk85.dim("\xB7")} ${paint("accent", strategyNudge.command)}`,
|
|
36919
37870
|
cardW
|
|
36920
37871
|
)
|
|
36921
37872
|
);
|
|
36922
37873
|
} else if (deepdiveNudge) {
|
|
36923
37874
|
push(
|
|
36924
37875
|
truncateVisible(
|
|
36925
|
-
` ${paint("warning", "\u2691")} ${
|
|
37876
|
+
` ${paint("warning", "\u2691")} ${chalk85.dim(deepdiveNudge.text)} ${chalk85.dim("\xB7")} ${paint("accent", deepdiveNudge.command)}`,
|
|
36926
37877
|
cardW
|
|
36927
37878
|
)
|
|
36928
37879
|
);
|
|
@@ -36945,6 +37896,7 @@ var init_welcome = __esm({
|
|
|
36945
37896
|
init_verify();
|
|
36946
37897
|
init_queries();
|
|
36947
37898
|
init_schema();
|
|
37899
|
+
init_registry();
|
|
36948
37900
|
NO_SUMMARY = "(no summary)";
|
|
36949
37901
|
CARD_MAX_W = 128;
|
|
36950
37902
|
CARD_SIDE_MARGIN = 6;
|
|
@@ -37003,6 +37955,21 @@ var init_deepdive_complete = __esm({
|
|
|
37003
37955
|
}
|
|
37004
37956
|
});
|
|
37005
37957
|
|
|
37958
|
+
// src/conversation/thinkwithme-complete.ts
|
|
37959
|
+
function thinkwithmeGhostSuffix(line) {
|
|
37960
|
+
if (!/^\/?thinkwithme/i.test(line)) return null;
|
|
37961
|
+
if (/\s/.test(line)) return null;
|
|
37962
|
+
const full = line.startsWith("/") ? "/thinkwithme" : "thinkwithme";
|
|
37963
|
+
if (full.toLowerCase() === line.toLowerCase()) return null;
|
|
37964
|
+
if (!full.toLowerCase().startsWith(line.toLowerCase())) return null;
|
|
37965
|
+
return full.slice(line.length);
|
|
37966
|
+
}
|
|
37967
|
+
var init_thinkwithme_complete = __esm({
|
|
37968
|
+
"src/conversation/thinkwithme-complete.ts"() {
|
|
37969
|
+
"use strict";
|
|
37970
|
+
}
|
|
37971
|
+
});
|
|
37972
|
+
|
|
37006
37973
|
// src/cli/repl.ts
|
|
37007
37974
|
var repl_exports = {};
|
|
37008
37975
|
__export(repl_exports, {
|
|
@@ -37014,7 +37981,7 @@ __export(repl_exports, {
|
|
|
37014
37981
|
});
|
|
37015
37982
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
37016
37983
|
import { clearLine as clearLine2, cursorTo as cursorTo2 } from "readline";
|
|
37017
|
-
import
|
|
37984
|
+
import chalk86 from "chalk";
|
|
37018
37985
|
import { join as join37 } from "path";
|
|
37019
37986
|
function buildPrompt(ctx) {
|
|
37020
37987
|
return buildConversationPrompt(ctx);
|
|
@@ -37047,6 +38014,9 @@ function inlineCommandSuggestion(line) {
|
|
|
37047
38014
|
if (/^\/deepdive(\s|$)/i.test(line)) {
|
|
37048
38015
|
return deepdiveGhostSuffix(line);
|
|
37049
38016
|
}
|
|
38017
|
+
if (/^\/thinkwithme/i.test(line)) {
|
|
38018
|
+
return thinkwithmeGhostSuffix(line);
|
|
38019
|
+
}
|
|
37050
38020
|
if (/\s/.test(line)) return null;
|
|
37051
38021
|
const matches = commandCompletionCandidates().filter((command) => command.startsWith(line));
|
|
37052
38022
|
if (matches.length === 0) return null;
|
|
@@ -37098,12 +38068,12 @@ function renderInlineSuggestion(rl, prompt, ctx) {
|
|
|
37098
38068
|
suggestionPainted = suffix !== null;
|
|
37099
38069
|
clearLine2(process.stdout, 0);
|
|
37100
38070
|
cursorTo2(process.stdout, 0);
|
|
37101
|
-
process.stdout.write(prompt + line + (suffix ?
|
|
38071
|
+
process.stdout.write(prompt + line + (suffix ? chalk86.dim(suffix) : ""));
|
|
37102
38072
|
cursorTo2(process.stdout, promptWidth + cursor);
|
|
37103
38073
|
}
|
|
37104
38074
|
function appendTurnLine(current, promptLabel, currentSummary) {
|
|
37105
|
-
const currentLine = currentSummary ? `${promptLabel} ${current} ${
|
|
37106
|
-
console.log(" " +
|
|
38075
|
+
const currentLine = currentSummary ? `${promptLabel} ${current} ${chalk86.white("\u2192")} ${currentSummary}` : `${promptLabel} ${current}`;
|
|
38076
|
+
console.log(" " + chalk86.dim(currentLine));
|
|
37107
38077
|
console.log();
|
|
37108
38078
|
}
|
|
37109
38079
|
async function goHome(ctx, version, history, opts) {
|
|
@@ -37113,7 +38083,7 @@ async function goHome(ctx, version, history, opts) {
|
|
|
37113
38083
|
process.stdout.write("\x1B[2J\x1B[H");
|
|
37114
38084
|
if (opts?.banner) {
|
|
37115
38085
|
console.log();
|
|
37116
|
-
console.log(" " + paint("accent", "\u2713") + " " +
|
|
38086
|
+
console.log(" " + paint("accent", "\u2713") + " " + chalk86.dim(opts.banner));
|
|
37117
38087
|
}
|
|
37118
38088
|
await printWelcome(ctx, version);
|
|
37119
38089
|
}
|
|
@@ -37136,11 +38106,11 @@ async function handleDispatchResult(result, ctx, version, history) {
|
|
|
37136
38106
|
case "unknown":
|
|
37137
38107
|
if (result.suggestion) {
|
|
37138
38108
|
console.log(
|
|
37139
|
-
" " +
|
|
38109
|
+
" " + chalk86.red(`Unknown command: ${result.token}.`) + chalk86.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk86.dim("?")
|
|
37140
38110
|
);
|
|
37141
38111
|
} else {
|
|
37142
38112
|
console.log(
|
|
37143
|
-
" " +
|
|
38113
|
+
" " + chalk86.red(`Unknown command: ${result.token}`) + chalk86.dim(" Type ") + paint("accent", "/help") + chalk86.dim(" to see available commands.")
|
|
37144
38114
|
);
|
|
37145
38115
|
}
|
|
37146
38116
|
break;
|
|
@@ -37164,14 +38134,14 @@ async function runRepl(ctx, version) {
|
|
|
37164
38134
|
});
|
|
37165
38135
|
ctx.rl = rl;
|
|
37166
38136
|
console.log();
|
|
37167
|
-
console.log(" " +
|
|
38137
|
+
console.log(" " + chalk86.dim("What do you want to look at?"));
|
|
37168
38138
|
console.log();
|
|
37169
38139
|
if (ctx.pendingUpdateCheck) {
|
|
37170
38140
|
void ctx.pendingUpdateCheck.then((result) => {
|
|
37171
|
-
if (result?.updateAvailable)
|
|
37172
|
-
|
|
37173
|
-
|
|
37174
|
-
|
|
38141
|
+
if (!result?.updateAvailable) return;
|
|
38142
|
+
if (result.latest === ctx.updateHomePaintedLatest) return;
|
|
38143
|
+
console.log(` ${formatUpdateNudge(result.current, result.latest)}`);
|
|
38144
|
+
console.log();
|
|
37175
38145
|
});
|
|
37176
38146
|
}
|
|
37177
38147
|
let pendingSuggestionRender = null;
|
|
@@ -37206,7 +38176,7 @@ async function runRepl(ctx, version) {
|
|
|
37206
38176
|
return;
|
|
37207
38177
|
}
|
|
37208
38178
|
sigintPrimed = true;
|
|
37209
|
-
console.log("\n " +
|
|
38179
|
+
console.log("\n " + chalk86.dim("Type /exit to quit, or press Ctrl+C again."));
|
|
37210
38180
|
};
|
|
37211
38181
|
rl.on("SIGINT", sigintHandler);
|
|
37212
38182
|
function shutdownRepl() {
|
|
@@ -37242,7 +38212,7 @@ async function runRepl(ctx, version) {
|
|
|
37242
38212
|
if (!typed && !enterAction) {
|
|
37243
38213
|
clearGhostRowAfterSubmit();
|
|
37244
38214
|
const coach = consumeOrientEmptyEnterCoach(ctx);
|
|
37245
|
-
if (coach) console.log(" " +
|
|
38215
|
+
if (coach) console.log(" " + chalk86.dim(coach));
|
|
37246
38216
|
continue;
|
|
37247
38217
|
}
|
|
37248
38218
|
const line = typed || enterAction.submit;
|
|
@@ -37293,9 +38263,9 @@ async function runRepl(ctx, version) {
|
|
|
37293
38263
|
ctx.wizardDepth = 0;
|
|
37294
38264
|
ctx.secretInputActive = false;
|
|
37295
38265
|
if (err instanceof Error && err.message === "Cancelled") {
|
|
37296
|
-
console.log(" " +
|
|
38266
|
+
console.log(" " + chalk86.dim("Cancelled."));
|
|
37297
38267
|
} else {
|
|
37298
|
-
console.error(" " +
|
|
38268
|
+
console.error(" " + chalk86.red("Error: " + String(err.message ?? err)));
|
|
37299
38269
|
}
|
|
37300
38270
|
}
|
|
37301
38271
|
}
|
|
@@ -37321,10 +38291,10 @@ async function runRepl(ctx, version) {
|
|
|
37321
38291
|
await closeSession(ctx);
|
|
37322
38292
|
}
|
|
37323
38293
|
if (isTranscriptActive(ctx.sessionId)) {
|
|
37324
|
-
console.log(" " +
|
|
37325
|
-
console.log(" " +
|
|
38294
|
+
console.log(" " + chalk86.dim("Transcript: ") + chalk86.dim(transcriptPathForSession(ctx.sessionId)));
|
|
38295
|
+
console.log(" " + chalk86.dim("Context brief: ") + chalk86.dim(contextDocPathForSession(ctx.sessionId)));
|
|
37326
38296
|
}
|
|
37327
|
-
console.log(" " +
|
|
38297
|
+
console.log(" " + chalk86.dim(randomGoodbye()));
|
|
37328
38298
|
}
|
|
37329
38299
|
function printHelpOneShot() {
|
|
37330
38300
|
printHelp();
|
|
@@ -37332,12 +38302,12 @@ function printHelpOneShot() {
|
|
|
37332
38302
|
function printHelp() {
|
|
37333
38303
|
console.log();
|
|
37334
38304
|
console.log(" " + sectionHeading("Conversation"));
|
|
37335
|
-
console.log(" " +
|
|
37336
|
-
console.log(" " +
|
|
37337
|
-
console.log(" " +
|
|
37338
|
-
console.log(" " +
|
|
37339
|
-
console.log(" " +
|
|
37340
|
-
console.log(" " +
|
|
38305
|
+
console.log(" " + chalk86.dim("Type the question. You do not need a slash command."));
|
|
38306
|
+
console.log(" " + chalk86.dim("Paste a CSV path or type ") + paint("accent", '"use demo data"') + chalk86.dim(" to load data."));
|
|
38307
|
+
console.log(" " + chalk86.dim("After analysis, type questions in English."));
|
|
38308
|
+
console.log(" " + chalk86.dim("Type ") + paint("accent", '"how should we fix this?"') + chalk86.dim(" to make a strategy."));
|
|
38309
|
+
console.log(" " + chalk86.dim("Type ") + paint("accent", '"ship a board deck"') + chalk86.dim(" to write a handoff."));
|
|
38310
|
+
console.log(" " + chalk86.dim("The ") + paint("accent", "ask \u203A") + chalk86.dim(" prompt shows brief or deep. Brief is the default after analysis."));
|
|
37341
38311
|
console.log();
|
|
37342
38312
|
console.log(" " + sectionHeading("Shortcuts"));
|
|
37343
38313
|
const shortcuts = [
|
|
@@ -37353,6 +38323,7 @@ function printHelp() {
|
|
|
37353
38323
|
["/end", "Close the session"],
|
|
37354
38324
|
["/recap", "Write a recap"],
|
|
37355
38325
|
["/connect", "Connect a key"],
|
|
38326
|
+
["/activate", "Paste a license key"],
|
|
37356
38327
|
["/upgrade", "Change to Pro"],
|
|
37357
38328
|
["/checkout", "Open signup"],
|
|
37358
38329
|
["/update", "Install the latest version"],
|
|
@@ -37361,11 +38332,11 @@ function printHelp() {
|
|
|
37361
38332
|
];
|
|
37362
38333
|
const maxW = Math.max(...shortcuts.map(([c]) => c.length)) + 2;
|
|
37363
38334
|
for (const [cmd, desc] of shortcuts) {
|
|
37364
|
-
console.log(` ${paint("accent", padRight(cmd, maxW))} ${
|
|
38335
|
+
console.log(` ${paint("accent", padRight(cmd, maxW))} ${chalk86.dim(desc)}`);
|
|
37365
38336
|
}
|
|
37366
38337
|
console.log();
|
|
37367
38338
|
console.log(" " + sectionHeading("Teach NTRP"));
|
|
37368
|
-
console.log(" " +
|
|
38339
|
+
console.log(" " + chalk86.dim("NTRP learns your business over time. There are three ways to teach it:"));
|
|
37369
38340
|
const teach = [
|
|
37370
38341
|
["/remember <fact>", "Store a fact, a decision, or a preference"],
|
|
37371
38342
|
["/recall [topic]", "Show what NTRP stores about your business"],
|
|
@@ -37374,13 +38345,13 @@ function printHelp() {
|
|
|
37374
38345
|
];
|
|
37375
38346
|
const teachMaxW = Math.max(...teach.map(([c]) => c.length)) + 2;
|
|
37376
38347
|
for (const [cmd, desc] of teach) {
|
|
37377
|
-
console.log(` ${paint("accent", padRight(cmd, teachMaxW))} ${
|
|
38348
|
+
console.log(` ${paint("accent", padRight(cmd, teachMaxW))} ${chalk86.dim(desc)}`);
|
|
37378
38349
|
}
|
|
37379
|
-
console.log(" " +
|
|
38350
|
+
console.log(" " + chalk86.dim("When a key is connected, NTRP stores a small number of facts when you close a session."));
|
|
37380
38351
|
console.log();
|
|
37381
|
-
console.log(" " +
|
|
38352
|
+
console.log(" " + chalk86.dim("Factory reset: type ") + paint("accent", "/scratch") + chalk86.dim("."));
|
|
37382
38353
|
console.log();
|
|
37383
|
-
console.log(" " +
|
|
38354
|
+
console.log(" " + chalk86.dim("These commands also work: ") + paint("accent", "/new") + chalk86.dim(", ") + paint("accent", "/diagnose") + chalk86.dim(", ") + paint("accent", "/metrics") + chalk86.dim(", ") + paint("accent", "/session") + chalk86.dim("."));
|
|
37384
38355
|
console.log();
|
|
37385
38356
|
}
|
|
37386
38357
|
var REPL_BUILTINS, ANSI_PATTERN, GOODBYES, GHOST_HINTS, ghostHintTurn, activeGhostHint, suggestionPainted;
|
|
@@ -37408,6 +38379,7 @@ var init_repl = __esm({
|
|
|
37408
38379
|
init_welcome();
|
|
37409
38380
|
init_registry();
|
|
37410
38381
|
init_deepdive_complete();
|
|
38382
|
+
init_thinkwithme_complete();
|
|
37411
38383
|
init_inline_suggestion();
|
|
37412
38384
|
REPL_BUILTINS = [
|
|
37413
38385
|
"/help",
|
|
@@ -37490,7 +38462,7 @@ init_emit();
|
|
|
37490
38462
|
init_errors2();
|
|
37491
38463
|
init_types2();
|
|
37492
38464
|
init_version();
|
|
37493
|
-
import
|
|
38465
|
+
import chalk87 from "chalk";
|
|
37494
38466
|
var VERSION = getInstalledVersion();
|
|
37495
38467
|
function exitIfVersionFlag(argv) {
|
|
37496
38468
|
const rest = argv.slice(2).filter((a) => a === "--version" || a === "-v");
|
|
@@ -37525,7 +38497,7 @@ async function main() {
|
|
|
37525
38497
|
quiet: args.globals.quiet
|
|
37526
38498
|
});
|
|
37527
38499
|
if (!ctx.execution.color) {
|
|
37528
|
-
|
|
38500
|
+
chalk87.level = 0;
|
|
37529
38501
|
}
|
|
37530
38502
|
if (args.globals.stdin) {
|
|
37531
38503
|
args.input = (await readStdin()).trim();
|
|
@@ -37538,16 +38510,16 @@ async function main() {
|
|
|
37538
38510
|
if (isStructuredOutput(ctx.execution)) {
|
|
37539
38511
|
emitError(cmd || "ntrp", new NtrpError("license_invalid", lic2.message, 3 /* Auth */));
|
|
37540
38512
|
}
|
|
37541
|
-
console.error(
|
|
38513
|
+
console.error(chalk87.red(`
|
|
37542
38514
|
${lic2.message}`));
|
|
37543
|
-
console.error(
|
|
38515
|
+
console.error(chalk87.dim(" Trial's over \u2014 /upgrade and paste your key.\n"));
|
|
37544
38516
|
process.exit(1);
|
|
37545
38517
|
}
|
|
37546
38518
|
}
|
|
37547
38519
|
const PROFILE_HINT_SKIP = /* @__PURE__ */ new Set(["onboard", "setup", "config", "connect", "activate", "help", "home", "exit", "quit", "clear", "profile", "progress", "deepdive"]);
|
|
37548
38520
|
if (!isProfileConfigured() && !PROFILE_HINT_SKIP.has(cmd) && !ctx.execution.quiet) {
|
|
37549
38521
|
console.error(
|
|
37550
|
-
" " +
|
|
38522
|
+
" " + chalk87.dim("Tip: run ") + paint("accent", "ntrp") + chalk87.dim(" interactively to set up your company profile for richer answers.")
|
|
37551
38523
|
);
|
|
37552
38524
|
}
|
|
37553
38525
|
const result = await dispatch(args.input, ctx);
|
|
@@ -37559,12 +38531,12 @@ async function main() {
|
|
|
37559
38531
|
}
|
|
37560
38532
|
if (result.suggestion) {
|
|
37561
38533
|
console.error(
|
|
37562
|
-
|
|
38534
|
+
chalk87.red(` Unknown command: ${result.token}.`) + chalk87.dim(" Did you mean ") + paint("accent", result.suggestion) + chalk87.dim("?")
|
|
37563
38535
|
);
|
|
37564
38536
|
} else {
|
|
37565
|
-
console.error(
|
|
38537
|
+
console.error(chalk87.red(` Unknown command: ${result.token}`));
|
|
37566
38538
|
}
|
|
37567
|
-
console.error(
|
|
38539
|
+
console.error(chalk87.dim(" Run 'ntrp' for the interactive prompt."));
|
|
37568
38540
|
process.exit(1);
|
|
37569
38541
|
break;
|
|
37570
38542
|
case "help":
|
|
@@ -37597,28 +38569,22 @@ async function main() {
|
|
|
37597
38569
|
ctx.datasetPath = datasetPathForSession2(ctx.sessionId);
|
|
37598
38570
|
await setActiveDbPath2(ctx.datasetPath);
|
|
37599
38571
|
const { completeInteractiveSetup: completeInteractiveSetup2 } = await Promise.resolve().then(() => (init_first_run(), first_run_exports));
|
|
37600
|
-
await completeInteractiveSetup2(ctx, { skipBrand: showedActivation });
|
|
37601
|
-
const {
|
|
37602
|
-
isCacheFresh: isCacheFresh2,
|
|
37603
|
-
loadUpdateCheckCache: loadUpdateCheckCache2
|
|
37604
|
-
} = await Promise.resolve().then(() => (init_update_check(), update_check_exports));
|
|
37605
38572
|
const {
|
|
37606
|
-
|
|
37607
|
-
|
|
37608
|
-
isNewerVersion: isNewerVersion2
|
|
38573
|
+
hydrateUpdateAvailableFromCache: hydrateUpdateAvailableFromCache2,
|
|
38574
|
+
startBackgroundUpdateCheck: startBackgroundUpdateCheck2
|
|
37609
38575
|
} = await Promise.resolve().then(() => (init_registry(), registry_exports));
|
|
37610
|
-
const
|
|
37611
|
-
|
|
37612
|
-
|
|
37613
|
-
|
|
37614
|
-
console.log(formatUpdateNudge2(currentVersion, cachedUpdate.latestVersion));
|
|
37615
|
-
}
|
|
37616
|
-
} else {
|
|
37617
|
-
ctx.pendingUpdateCheck = checkForUpdate2({ timeoutMs: 200 });
|
|
37618
|
-
}
|
|
38576
|
+
const { consumeJustUpdatedEnv: consumeJustUpdatedEnv2 } = await Promise.resolve().then(() => (init_relaunch(), relaunch_exports));
|
|
38577
|
+
ctx.updateAvailable = hydrateUpdateAvailableFromCache2(VERSION);
|
|
38578
|
+
startBackgroundUpdateCheck2(ctx);
|
|
38579
|
+
await completeInteractiveSetup2(ctx, { skipBrand: showedActivation });
|
|
37619
38580
|
const { startSessionTranscript: startSessionTranscript2, stopSessionTranscript: stopSessionTranscript2 } = await Promise.resolve().then(() => (init_transcript(), transcript_exports));
|
|
37620
38581
|
startSessionTranscript2(ctx);
|
|
37621
38582
|
const { printWelcome: printWelcome2 } = await Promise.resolve().then(() => (init_welcome(), welcome_exports));
|
|
38583
|
+
const justUpdated = consumeJustUpdatedEnv2();
|
|
38584
|
+
if (justUpdated) {
|
|
38585
|
+
console.log();
|
|
38586
|
+
console.log(" " + paint("accent", "\u2713") + " " + chalk87.dim(`Now running v${justUpdated.to}`));
|
|
38587
|
+
}
|
|
37622
38588
|
await printWelcome2(ctx, VERSION);
|
|
37623
38589
|
await runRepl(ctx, VERSION);
|
|
37624
38590
|
stopSessionTranscript2();
|